From d590ce7675752b46f4467c4563295f4107e3147d Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Thu, 3 Dec 2020 19:12:53 +0000 Subject: [PATCH] map: add 3 DenseArray methods for bootstrapping (#7113) --- vlib/builtin/map.v | 17 +++++++++++++++++ vlib/v/gen/auto_str_methods.v | 10 +++------- vlib/v/gen/cgen.v | 13 ++++++------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/vlib/builtin/map.v b/vlib/builtin/map.v index 4528637a6d..d2ca3e59fb 100644 --- a/vlib/builtin/map.v +++ b/vlib/builtin/map.v @@ -117,6 +117,23 @@ fn new_dense_array(value_bytes int) DenseArray { } } +[inline] +fn (d &DenseArray) key(i int) voidptr { + return unsafe {voidptr(d.keys + i)} +} + +// for cgen +[inline] +fn (d &DenseArray) value(i int) voidptr { + return unsafe {voidptr(d.values + i * d.value_bytes)} +} + +[inline] +fn (d &DenseArray) has_index(i int) bool { + pkey := unsafe {d.keys + i} + return pkey.str != 0 +} + // Push element to array and return index // The growth-factor is roughly 1.125 `(x + (x >> 3))` [inline] diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index d0ba04fc75..0481a6b0d9 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -258,7 +258,6 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) if !val_sym.has_method('str') { g.gen_str_for_type(info.value_type) } - zero := g.type_default(info.value_type) g.type_definitions.writeln('static string ${str_fn_name}($styp m); // auto') g.auto_str_funcs.writeln('static string ${str_fn_name}($styp m) { return indent_${str_fn_name}(m, 0);}') g.type_definitions.writeln('static string indent_${str_fn_name}($styp m, int indent_count); // auto') @@ -266,14 +265,11 @@ fn (mut g Gen) gen_str_for_map(info table.Map, styp string, str_fn_name string) g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.len*10);') g.auto_str_funcs.writeln('\tstrings__Builder_write(&sb, _SLIT("{"));') g.auto_str_funcs.writeln('\tfor (unsigned int i = 0; i < m.key_values.len; ++i) {') - g.auto_str_funcs.writeln('\t\tif (m.key_values.keys[i].str == 0) { continue; }') - g.auto_str_funcs.writeln('\t\tstring key = (*(string*)DenseArray_get(m.key_values, i));') + g.auto_str_funcs.writeln('\t\tif (!DenseArray_has_index(&m.key_values, i)) { continue; }') + g.auto_str_funcs.writeln('\t\tstring key = *(string*)DenseArray_key(&m.key_values, i);') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, key));') g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _SLIT(": "));') - g.auto_str_funcs.write('\t$val_styp it = (*($val_styp*)map_get(') - g.auto_str_funcs.write('m, (*(string*)DenseArray_get(m.key_values, i))') - g.auto_str_funcs.write(', ') - g.auto_str_funcs.writeln(' &($val_styp[]) { $zero }));') + g.auto_str_funcs.writeln('\t\t$val_styp it = *($val_styp*)DenseArray_value(&m.key_values, i);') if val_sym.kind == .string { g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, _STR("\'%.*s\\000\'", 2, it));') } else if val_sym.kind == .struct_ && !val_sym.has_method('str') { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 4f8b257f25..93010d3e28 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1221,28 +1221,27 @@ fn (mut g Gen) for_in(it ast.ForInStmt) { g.expr(it.cond) g.writeln(';') g.writeln('for (int $idx = 0; $idx < (int)${atmp}.key_values.len; ++$idx) {') - g.writeln('\tif (${atmp}.key_values.keys[$idx].str == 0) {continue;}') + g.writeln('\tif (!DenseArray_has_index(&${atmp}.key_values, $idx)) {continue;}') if it.key_var != '_' { key_styp := g.typ(it.key_type) key := c_name(it.key_var) + g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&${atmp}.key_values, $idx);') // TODO: analyze whether it.key_type has a .clone() method and call .clone() for all types: if it.key_type == table.string_type { - g.writeln('\t$key_styp $key = /*key*/ string_clone(${atmp}.key_values.keys[$idx]);') - } else { - g.writeln('\t$key_styp $key = /*key*/ ${atmp}.key_values.keys[$idx];') + g.writeln('\t$key = string_clone($key);') } } if it.val_var != '_' { val_sym := g.table.get_type_symbol(it.val_type) - valstr := '(void*)(${atmp}.key_values.values + $idx * (u32)(${atmp}.value_bytes))' if val_sym.kind == .function { g.write('\t') g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var)) - g.writeln(' = (*(voidptr*)$valstr);') + g.write(' = (*(voidptr*)') } else { val_styp := g.typ(it.val_type) - g.writeln('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)$valstr);') + g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)') } + g.writeln('DenseArray_value(&${atmp}.key_values, $idx));') } g.stmts(it.stmts) if it.key_type == table.string_type && !g.is_builtin_mod {