use pod_vector for small vectors

This commit is contained in:
blueloveTH 2024-02-18 17:51:35 +08:00
parent 635aae921f
commit 97c923e514
18 changed files with 40 additions and 45 deletions

View File

@ -1,5 +1,5 @@
SRC=$(find src/ -name "*.cpp") SRC=$(find src/ -name "*.cpp")
FLAGS="-std=c++17 -O1 -stdlib=libc++ -Iinclude -W -Wno-unused-parameter -Wno-sign-compare" FLAGS="-std=c++17 -O1 -stdlib=libc++ -Iinclude -W -Wno-unused-parameter"
clang++ $FLAGS -o main -O1 src2/main.cpp $SRC clang++ $FLAGS -o main -O1 src2/main.cpp $SRC

View File

@ -71,7 +71,7 @@ struct CodeObject {
std::vector<int> iblocks; // block index for each bytecode std::vector<int> iblocks; // block index for each bytecode
std::vector<LineInfo> lines; std::vector<LineInfo> lines;
List consts; List consts;
std::vector<StrName> varnames; // local variables pod_vector<StrName> varnames; // local variables
NameDictInt varnames_inv; NameDictInt varnames_inv;
std::vector<CodeBlock> blocks = { CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0) }; std::vector<CodeBlock> blocks = { CodeBlock(CodeBlockType::NO_BLOCK, -1, 0, 0) };
NameDictInt labels; NameDictInt labels;
@ -95,8 +95,8 @@ struct FuncDecl {
PyObject* value; // default value PyObject* value; // default value
}; };
CodeObject_ code; // code object of this function CodeObject_ code; // code object of this function
std::vector<int> args; // indices in co->varnames pod_vector<int> args; // indices in co->varnames
std::vector<KwArg> kwargs; // indices in co->varnames pod_vector<KwArg> kwargs; // indices in co->varnames
int starred_arg = -1; // index in co->varnames, -1 if no *arg int starred_arg = -1; // index in co->varnames, -1 if no *arg
int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
bool nested = false; // whether this function is nested bool nested = false; // whether this function is nested
@ -109,7 +109,7 @@ struct FuncDecl {
void add_kwarg(int index, StrName key, PyObject* value){ void add_kwarg(int index, StrName key, PyObject* value){
kw_to_index.set(key, index); kw_to_index.set(key, index);
kwargs.push_back({index, key, value}); kwargs.push_back(KwArg{index, key, value});
} }
void _gc_mark() const; void _gc_mark() const;

View File

@ -30,7 +30,7 @@ struct SourceData {
CompileMode mode; CompileMode mode;
Str source; Str source;
std::vector<const char*> line_starts; pod_vector<const char*> line_starts;
SourceData(std::string_view source, const Str& filename, CompileMode mode); SourceData(std::string_view source, const Str& filename, CompileMode mode);
SourceData(const Str& filename, CompileMode mode); SourceData(const Str& filename, CompileMode mode);

View File

@ -314,7 +314,7 @@ struct BinaryExpr: Expr{
Expr_ lhs; Expr_ lhs;
Expr_ rhs; Expr_ rhs;
bool is_compare() const override; bool is_compare() const override;
void _emit_compare(CodeEmitContext* ctx, std::vector<int>& jmps); void _emit_compare(CodeEmitContext* ctx, pod_vector<int>& jmps);
void emit_(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };

View File

@ -75,7 +75,6 @@ struct Bytes{
Bytes(const Str& str): Bytes(str.sv()) {} Bytes(const Str& str): Bytes(str.sv()) {}
operator bool() const noexcept { return _data != nullptr; } operator bool() const noexcept { return _data != nullptr; }
Bytes(const std::vector<unsigned char>& v);
Bytes(std::string_view sv); Bytes(std::string_view sv);
Bytes(const Bytes& rhs); Bytes(const Bytes& rhs);
Bytes(Bytes&& rhs) noexcept; Bytes(Bytes&& rhs) noexcept;

View File

@ -76,8 +76,8 @@ struct Str{
int index(const Str& sub, int start=0) const; int index(const Str& sub, int start=0) const;
Str replace(char old, char new_) const; Str replace(char old, char new_) const;
Str replace(const Str& old, const Str& new_, int count=-1) const; Str replace(const Str& old, const Str& new_, int count=-1) const;
std::vector<std::string_view> split(const Str& sep) const; pod_vector<std::string_view> split(const Str& sep) const;
std::vector<std::string_view> split(char sep) const; pod_vector<std::string_view> split(char sep) const;
int count(const Str& sub) const; int count(const Str& sub) const;
/*************unicode*************/ /*************unicode*************/

View File

@ -54,7 +54,7 @@ struct PyTypeInfo{
StrName name; StrName name;
bool subclass_enabled; bool subclass_enabled;
std::vector<StrName> annotated_fields = {}; pod_vector<StrName> annotated_fields = {};
// cached special methods // cached special methods
// unary operators // unary operators
@ -385,7 +385,7 @@ public:
struct ImportContext{ struct ImportContext{
std::vector<Str> pending; std::vector<Str> pending;
std::vector<bool> pending_is_init; // a.k.a __init__.py pod_vector<bool> pending_is_init; // a.k.a __init__.py
struct Temp{ struct Temp{
ImportContext* ctx; ImportContext* ctx;
Temp(ImportContext* ctx, Str name, bool is_init) : ctx(ctx){ Temp(ImportContext* ctx, Str name, bool is_init) : ctx(ctx){

View File

@ -39,7 +39,7 @@ namespace pkpy{
ctx()->co->end_line = tokens[j].line; ctx()->co->end_line = tokens[j].line;
// some check here // some check here
std::vector<Bytecode>& codes = ctx()->co->codes; auto& codes = ctx()->co->codes;
if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){ if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){
SyntaxError("maximum number of local variables exceeded"); SyntaxError("maximum number of local variables exceeded");
} }
@ -659,7 +659,7 @@ __EAT_DOTS_END:
void Compiler::compile_try_except() { void Compiler::compile_try_except() {
ctx()->enter_block(CodeBlockType::TRY_EXCEPT); ctx()->enter_block(CodeBlockType::TRY_EXCEPT);
compile_block_body(); compile_block_body();
std::vector<int> patches = { pod_vector<int> patches = {
ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE) ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE)
}; };
ctx()->exit_block(); ctx()->exit_block();

View File

@ -24,7 +24,7 @@ namespace pkpy{
if(lineno == -1) return {nullptr, nullptr}; if(lineno == -1) return {nullptr, nullptr};
lineno -= 1; lineno -= 1;
if(lineno < 0) lineno = 0; if(lineno < 0) lineno = 0;
const char* _start = line_starts.at(lineno); const char* _start = line_starts[lineno];
const char* i = _start; const char* i = _start;
// max 300 chars // max 300 chars
while(*i != '\n' && *i != '\0' && i-_start < 300) i++; while(*i != '\n' && *i != '\0' && i-_start < 300) i++;

View File

@ -55,7 +55,7 @@ namespace pkpy{
int CodeEmitContext::emit_(Opcode opcode, uint16_t arg, int line, bool is_virtual) { int CodeEmitContext::emit_(Opcode opcode, uint16_t arg, int line, bool is_virtual) {
co->codes.push_back(Bytecode{(uint8_t)opcode, arg}); co->codes.push_back(Bytecode{(uint8_t)opcode, arg});
co->iblocks.push_back(curr_block_i); co->iblocks.push_back(curr_block_i);
co->lines.push_back({line, is_virtual}); co->lines.push_back(CodeObject::LineInfo{line, is_virtual});
int i = co->codes.size() - 1; int i = co->codes.size() - 1;
if(line == BC_KEEPLINE){ if(line == BC_KEEPLINE){
if(i >= 1) co->lines[i].lineno = co->lines[i-1].lineno; if(i >= 1) co->lines[i].lineno = co->lines[i-1].lineno;
@ -613,7 +613,7 @@ namespace pkpy{
} }
} }
void BinaryExpr::_emit_compare(CodeEmitContext* ctx, std::vector<int>& jmps){ void BinaryExpr::_emit_compare(CodeEmitContext* ctx, pod_vector<int>& jmps){
if(lhs->is_compare()){ if(lhs->is_compare()){
static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps); static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps);
}else{ }else{
@ -637,7 +637,7 @@ namespace pkpy{
} }
void BinaryExpr::emit_(CodeEmitContext* ctx) { void BinaryExpr::emit_(CodeEmitContext* ctx) {
std::vector<int> jmps; pod_vector<int> jmps;
if(is_compare() && lhs->is_compare()){ if(is_compare() && lhs->is_compare()){
// (a < b) < c // (a < b) < c
static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps); static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps);

View File

@ -109,8 +109,8 @@ static bool is_unicode_Lo_char(uint32_t c) {
} }
} }
// handle multibyte char // handle multibyte char
std::string u8str(curr_char, u8bytes); Str u8str(curr_char, u8bytes);
if(u8str.size() != u8bytes) return 2; if(u8str.size != u8bytes) return 2;
uint32_t value = 0; uint32_t value = 0;
for(int k=0; k < u8bytes; k++){ for(int k=0; k < u8bytes; k++){
uint8_t b = u8str[k]; uint8_t b = u8str[k];
@ -204,7 +204,7 @@ static bool is_unicode_Lo_char(uint32_t c) {
Str Lexer::eat_string_until(char quote, bool raw) { Str Lexer::eat_string_until(char quote, bool raw) {
bool quote3 = match_n_chars(2, quote); bool quote3 = match_n_chars(2, quote);
std::vector<char> buff; pod_vector<char> buff;
while (true) { while (true) {
char c = eatchar_include_newline(); char c = eatchar_include_newline();
if (c == quote){ if (c == quote){

View File

@ -123,8 +123,8 @@ struct DoubleLinkedList{
template<int __BlockSize=128> template<int __BlockSize=128>
struct MemoryPool{ struct MemoryPool{
static const size_t __MaxBlocks = 256*1024 / __BlockSize; static const int __MaxBlocks = 256*1024 / __BlockSize;
static const size_t __MinArenaCount = PK_GC_MIN_THRESHOLD*100 / (256*1024); static const int __MinArenaCount = PK_GC_MIN_THRESHOLD*100 / (256*1024);
struct Block{ struct Block{
void* arena; void* arena;

View File

@ -14,11 +14,6 @@ namespace pkpy{
} }
bool Bytes::operator!=(const Bytes& rhs) const{ return !(*this == rhs); } bool Bytes::operator!=(const Bytes& rhs) const{ return !(*this == rhs); }
Bytes::Bytes(const std::vector<unsigned char>& v){
_data = new unsigned char[v.size()];
_size = v.size();
for(int i=0; i<_size; i++) _data[i] = v[i];
}
Bytes::Bytes(std::string_view sv){ Bytes::Bytes(std::string_view sv){
_data = new unsigned char[sv.size()]; _data = new unsigned char[sv.size()];
_size = sv.size(); _size = sv.size();

View File

@ -299,11 +299,11 @@ void init_builtins(VM* _vm) {
_vm->bind_func<1>(_vm->builtins, "dir", [](VM* vm, ArgsView args) { _vm->bind_func<1>(_vm->builtins, "dir", [](VM* vm, ArgsView args) {
std::set<StrName> names; std::set<StrName> names;
if(!is_tagged(args[0]) && args[0]->is_attr_valid()){ if(!is_tagged(args[0]) && args[0]->is_attr_valid()){
std::vector<StrName> keys = args[0]->attr().keys(); auto keys = args[0]->attr().keys();
names.insert(keys.begin(), keys.end()); names.insert(keys.begin(), keys.end());
} }
const NameDict& t_attr = vm->_t(args[0])->attr(); const NameDict& t_attr = vm->_t(args[0])->attr();
std::vector<StrName> keys = t_attr.keys(); auto keys = t_attr.keys();
names.insert(keys.begin(), keys.end()); names.insert(keys.begin(), keys.end());
List ret; List ret;
for (StrName name : names) ret.push_back(VAR(name.sv())); for (StrName name : names) ret.push_back(VAR(name.sv()));
@ -568,7 +568,7 @@ void init_builtins(VM* _vm) {
const Str& self = _CAST(Str&, args[0]); const Str& self = _CAST(Str&, args[0]);
const Str& sep = CAST(Str&, args[1]); const Str& sep = CAST(Str&, args[1]);
if(sep.empty()) vm->ValueError("empty separator"); if(sep.empty()) vm->ValueError("empty separator");
std::vector<std::string_view> parts; pod_vector<std::string_view> parts;
if(sep.size == 1){ if(sep.size == 1){
parts = self.split(sep[0]); parts = self.split(sep[0]);
}else{ }else{
@ -581,7 +581,7 @@ void init_builtins(VM* _vm) {
_vm->bind(_vm->_t(VM::tp_str), "splitlines(self)", [](VM* vm, ArgsView args) { _vm->bind(_vm->_t(VM::tp_str), "splitlines(self)", [](VM* vm, ArgsView args) {
const Str& self = _CAST(Str&, args[0]); const Str& self = _CAST(Str&, args[0]);
std::vector<std::string_view> parts; pod_vector<std::string_view> parts;
parts = self.split('\n'); parts = self.split('\n');
List ret(parts.size()); List ret(parts.size());
for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i])); for(int i=0; i<parts.size(); i++) ret[i] = VAR(Str(parts[i]));
@ -1048,13 +1048,14 @@ void init_builtins(VM* _vm) {
// tp_bytes // tp_bytes
_vm->bind_constructor<2>(_vm->_t(VM::tp_bytes), [](VM* vm, ArgsView args){ _vm->bind_constructor<2>(_vm->_t(VM::tp_bytes), [](VM* vm, ArgsView args){
List& list = CAST(List&, args[1]); List& list = CAST(List&, args[1]);
std::vector<unsigned char> buffer(list.size()); pod_vector<unsigned char> buffer(list.size());
for(int i=0; i<list.size(); i++){ for(int i=0; i<list.size(); i++){
i64 b = CAST(i64, list[i]); i64 b = CAST(i64, list[i]);
if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)"); if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)");
buffer[i] = (char)b; buffer[i] = (char)b;
} }
return VAR(Bytes(buffer)); auto detached = buffer.detach();
return VAR(Bytes(detached.first, detached.second));
}); });
_vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyObject* obj, PyObject* index) { _vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyObject* obj, PyObject* index) {

View File

@ -30,7 +30,7 @@ void LineProfiler::_step(FrameId frame){
_step_end(frame, line); _step_end(frame, line);
} }
std::vector<_LineRecord>& file_records = records[filename]; auto& file_records = records[filename];
if(file_records.empty()){ if(file_records.empty()){
// initialize file_records // initialize file_records
int total_lines = frame->co->src->line_starts.size(); int total_lines = frame->co->src->line_starts.size();

View File

@ -61,7 +61,7 @@ struct Random{
Random& self = _CAST(Random&, args[0]); Random& self = _CAST(Random&, args[0]);
auto [data, size] = vm->_cast_array(args[1]); auto [data, size] = vm->_cast_array(args[1]);
if(size == 0) vm->IndexError("cannot choose from an empty sequence"); if(size == 0) vm->IndexError("cannot choose from an empty sequence");
std::vector<f64> cum_weights(size); pod_vector<f64> cum_weights(size);
if(args[2] == vm->None){ if(args[2] == vm->None){
for(int i = 0; i < size; i++) cum_weights[i] = i + 1; for(int i = 0; i < size; i++) cum_weights[i] = i + 1;
}else{ }else{

View File

@ -14,7 +14,7 @@ int utf8len(unsigned char c, bool suppress){
} }
#define PK_STR_ALLOCATE() \ #define PK_STR_ALLOCATE() \
if(this->size < sizeof(this->_inlined)){ \ if(this->size < (int)sizeof(this->_inlined)){ \
this->data = this->_inlined; \ this->data = this->_inlined; \
}else{ \ }else{ \
this->data = (char*)pool64_alloc(this->size+1); \ this->data = (char*)pool64_alloc(this->size+1); \
@ -345,8 +345,8 @@ int utf8len(unsigned char c, bool suppress){
return _byte_index_to_unicode(size); return _byte_index_to_unicode(size);
} }
std::vector<std::string_view> Str::split(const Str& sep) const{ pod_vector<std::string_view> Str::split(const Str& sep) const{
std::vector<std::string_view> result; pod_vector<std::string_view> result;
std::string_view tmp; std::string_view tmp;
int start = 0; int start = 0;
while(true){ while(true){
@ -361,8 +361,8 @@ int utf8len(unsigned char c, bool suppress){
return result; return result;
} }
std::vector<std::string_view> Str::split(char sep) const{ pod_vector<std::string_view> Str::split(char sep) const{
std::vector<std::string_view> result; pod_vector<std::string_view> result;
int i = 0; int i = 0;
for(int j = 0; j < size; j++){ for(int j = 0; j < size; j++){
if(data[j] == sep){ if(data[j] == sep){

View File

@ -278,7 +278,7 @@ namespace pkpy{
PyObject* VM::py_import(Str path, bool throw_err){ PyObject* VM::py_import(Str path, bool throw_err){
if(path.empty()) vm->ValueError("empty module name"); if(path.empty()) vm->ValueError("empty module name");
static auto f_join = [](const std::vector<std::string_view>& cpnts){ static auto f_join = [](const pod_vector<std::string_view>& cpnts){
SStream ss; SStream ss;
for(int i=0; i<cpnts.size(); i++){ for(int i=0; i<cpnts.size(); i++){
if(i != 0) ss << "."; if(i != 0) ss << ".";
@ -294,7 +294,7 @@ namespace pkpy{
Str curr_path = _import_context.pending.back(); Str curr_path = _import_context.pending.back();
bool curr_is_init = _import_context.pending_is_init.back(); bool curr_is_init = _import_context.pending_is_init.back();
// convert relative path to absolute path // convert relative path to absolute path
std::vector<std::string_view> cpnts = curr_path.split('.'); pod_vector<std::string_view> cpnts = curr_path.split('.');
int prefix = 0; // how many dots in the prefix int prefix = 0; // how many dots in the prefix
for(int i=0; i<path.length(); i++){ for(int i=0; i<path.length(); i++){
if(path[i] == '.') prefix++; if(path[i] == '.') prefix++;
@ -314,7 +314,7 @@ namespace pkpy{
PyObject* ext_mod = _modules.try_get(name); PyObject* ext_mod = _modules.try_get(name);
if(ext_mod != nullptr) return ext_mod; if(ext_mod != nullptr) return ext_mod;
std::vector<std::string_view> path_cpnts = path.split('.'); pod_vector<std::string_view> path_cpnts = path.split('.');
// check circular import // check circular import
if(_import_context.pending.size() > 128){ if(_import_context.pending.size() > 128){
ImportError("maximum recursion depth exceeded while importing"); ImportError("maximum recursion depth exceeded while importing");
@ -600,7 +600,7 @@ Str VM::disassemble(CodeObject_ co){
return s + std::string(n - s.length(), ' '); return s + std::string(n - s.length(), ' ');
}; };
std::vector<int> jumpTargets; pod_vector<int> jumpTargets;
for(auto byte : co->codes){ for(auto byte : co->codes){
if(byte.op == OP_JUMP_ABSOLUTE || byte.op == OP_POP_JUMP_IF_FALSE || byte.op == OP_SHORTCUT_IF_FALSE_OR_POP || byte.op == OP_FOR_ITER){ if(byte.op == OP_JUMP_ABSOLUTE || byte.op == OP_POP_JUMP_IF_FALSE || byte.op == OP_SHORTCUT_IF_FALSE_OR_POP || byte.op == OP_FOR_ITER){
jumpTargets.push_back(byte.arg); jumpTargets.push_back(byte.arg);