diff options
author | bfredl <bjorn.linse@gmail.com> | 2024-02-19 21:21:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-19 21:21:05 +0100 |
commit | 8952a89db588db10a9dba16356f9bbd35ca5fabb (patch) | |
tree | ac34d55b77303deadef6a7ed3f4202259324a249 | |
parent | 8fdc84d0aaec63d57203bdef4b88047479ad4fc1 (diff) | |
parent | 404707c7606389ccb6c6062bfe9e2ff30a2552af (diff) | |
download | rneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.tar.gz rneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.tar.bz2 rneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.zip |
Merge pull request #27534 from bfredl/userarena
refactor(api): next PR to make use of the arena
-rw-r--r-- | src/nvim/api/command.c | 10 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 16 | ||||
-rw-r--r-- | src/nvim/api/tabpage.c | 10 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 110 | ||||
-rw-r--r-- | src/nvim/ops.c | 3 | ||||
-rw-r--r-- | src/nvim/runtime.c | 12 | ||||
-rw-r--r-- | src/nvim/usercmd.c | 55 |
7 files changed, 107 insertions, 109 deletions
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index a21c9e70a7..f2d5342a5f 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -1166,10 +1166,10 @@ err: /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err) +Dictionary nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) FUNC_API_SINCE(4) { - return nvim_buf_get_commands(-1, opts, err); + return nvim_buf_get_commands(-1, opts, arena, err); } /// Gets a map of buffer-local |user-commands|. @@ -1179,7 +1179,7 @@ Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err) /// @param[out] err Error details, if any. /// /// @returns Map of maps describing commands. -Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error *err) +Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err) FUNC_API_SINCE(4) { bool global = (buffer == -1); @@ -1192,12 +1192,12 @@ Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error api_set_error(err, kErrorTypeValidation, "builtin=true not implemented"); return (Dictionary)ARRAY_DICT_INIT; } - return commands_array(NULL); + return commands_array(NULL, arena); } buf_T *buf = find_buffer_by_handle(buffer, err); if (opts->builtin || !buf) { return (Dictionary)ARRAY_DICT_INIT; } - return commands_array(buf); + return commands_array(buf, arena); } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 63c5689109..14f4046a56 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -456,9 +456,10 @@ String ga_take_string(garray_T *ga) /// @param input Binary string /// @param crlf Also break lines at CR and CRLF. /// @return [allocated] String array -Array string_to_array(const String input, bool crlf) +Array string_to_array(const String input, bool crlf, Arena *arena) { - Array ret = ARRAY_DICT_INIT; + ArrayBuilder ret = ARRAY_DICT_INIT; + kvi_init(ret); for (size_t i = 0; i < input.size; i++) { const char *start = input.data + i; const char *end = start; @@ -473,20 +474,17 @@ Array string_to_array(const String input, bool crlf) if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) { i += 1; // Advance past CRLF. } - String s = { - .size = line_len, - .data = xmemdupz(start, line_len), - }; + String s = CBUF_TO_ARENA_STR(arena, start, line_len); memchrsub(s.data, NUL, NL, line_len); - ADD(ret, STRING_OBJ(s)); + kvi_push(ret, STRING_OBJ(s)); // If line ends at end-of-buffer, add empty final item. // This is "readfile()-style", see also ":help channel-lines". if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) { - ADD(ret, STRING_OBJ(STRING_INIT)); + kvi_push(ret, STRING_OBJ(STRING_INIT)); } } - return ret; + return arena_take_arraybuilder(arena, &ret); } /// Normalizes 0-based indexes to buffer line numbers. diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 109075df8e..040abb1e3f 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -19,7 +19,7 @@ /// @param tabpage Tabpage handle, or 0 for current tabpage /// @param[out] err Error details, if any /// @return List of windows in `tabpage` -ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) +ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Arena *arena, Error *err) FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; @@ -29,15 +29,15 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) return rv; } + size_t n = 0; FOR_ALL_WINDOWS_IN_TAB(wp, tab) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + rv = arena_array(arena, n); FOR_ALL_WINDOWS_IN_TAB(wp, tab) { - rv.items[i++] = WINDOW_OBJ(wp->handle); + ADD_C(rv, WINDOW_OBJ(wp->handle)); } return rv; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index d161dca050..e472f5d160 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -543,17 +543,22 @@ Integer nvim_strwidth(String text, Error *err) /// Gets the paths contained in |runtime-search-path|. /// /// @return List of paths -ArrayOf(String) nvim_list_runtime_paths(Error *err) +ArrayOf(String) nvim_list_runtime_paths(Arena *arena, Error *err) FUNC_API_SINCE(1) { - return nvim_get_runtime_file(NULL_STRING, true, err); + return nvim_get_runtime_file(NULL_STRING, true, arena, err); } -Array nvim__runtime_inspect(void) +Array nvim__runtime_inspect(Arena *arena) { - return runtime_inspect(); + return runtime_inspect(arena); } +typedef struct { + ArrayBuilder rv; + Arena *arena; +} RuntimeCookie; + /// Find files in runtime directories /// /// "name" can contain wildcards. For example @@ -566,25 +571,27 @@ Array nvim__runtime_inspect(void) /// @param name pattern of files to search for /// @param all whether to return all matches or only the first /// @return list of absolute paths to the found files -ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) +ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Error *err) FUNC_API_SINCE(7) FUNC_API_FAST { - Array rv = ARRAY_DICT_INIT; + RuntimeCookie cookie = { .rv = ARRAY_DICT_INIT, .arena = arena, }; + kvi_init(cookie.rv); int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); TRY_WRAP(err, { - do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &rv); + do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie); }); - return rv; + return arena_take_arraybuilder(arena, &cookie.rv); } -static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *cookie) +static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c) { - Array *rv = (Array *)cookie; + RuntimeCookie *cookie = (RuntimeCookie *)c; for (int i = 0; i < num_fnames; i++) { - ADD(*rv, CSTR_TO_OBJ(fnames[i])); + // TODO(bfredl): consider memory management of gen_expand_wildcards() itself + kvi_push(cookie->rv, CSTR_TO_ARENA_OBJ(cookie->arena, fnames[i])); if (!all) { return true; } @@ -825,20 +832,19 @@ void nvim_err_writeln(String str) /// Use |nvim_buf_is_loaded()| to check if a buffer is loaded. /// /// @return List of buffer handles -ArrayOf(Buffer) nvim_list_bufs(void) +ArrayOf(Buffer) nvim_list_bufs(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_BUFFERS(b) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_BUFFERS(b) { - rv.items[i++] = BUFFER_OBJ(b->handle); + ADD_C(rv, BUFFER_OBJ(b->handle)); } return rv; @@ -880,20 +886,19 @@ void nvim_set_current_buf(Buffer buffer, Error *err) /// Gets the current list of window handles. /// /// @return List of window handles -ArrayOf(Window) nvim_list_wins(void) +ArrayOf(Window) nvim_list_wins(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_TAB_WINDOWS(tp, wp) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_TAB_WINDOWS(tp, wp) { - rv.items[i++] = WINDOW_OBJ(wp->handle); + ADD_C(rv, WINDOW_OBJ(wp->handle)); } return rv; @@ -1117,20 +1122,19 @@ void nvim_chan_send(Integer chan, String data, Error *err) /// Gets the current list of tabpage handles. /// /// @return List of tabpage handles -ArrayOf(Tabpage) nvim_list_tabpages(void) +ArrayOf(Tabpage) nvim_list_tabpages(Arena *arena) FUNC_API_SINCE(1) { - Array rv = ARRAY_DICT_INIT; + size_t n = 0; FOR_ALL_TABS(tp) { - rv.size++; + n++; } - rv.items = xmalloc(sizeof(Object) * rv.size); - size_t i = 0; + Array rv = arena_array(arena, n); FOR_ALL_TABS(tp) { - rv.items[i++] = TABPAGE_OBJ(tp->handle); + ADD_C(rv, TABPAGE_OBJ(tp->handle)); } return rv; @@ -1201,14 +1205,13 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { return false; }); - Array lines = ARRAY_DICT_INIT; if (phase == -1 || phase == 1) { // Start of paste-stream. draining = false; } else if (draining) { // Skip remaining chunks. Report error only once per "stream". goto theend; } - lines = string_to_array(data, crlf); + Array lines = string_to_array(data, crlf, arena); MAXSIZE_TEMP_ARRAY(args, 2); ADD_C(args, ARRAY_OBJ(lines)); ADD_C(args, INTEGER_OBJ(phase)); @@ -1239,7 +1242,6 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error AppendCharToRedobuff(ESC); // Dot-repeat. } theend: - api_free_array(lines); if (cancel || phase == -1 || phase == 3) { // End of paste-stream. draining = false; } @@ -1260,24 +1262,27 @@ theend: /// @param after If true insert after cursor (like |p|), or before (like |P|). /// @param follow If true place cursor at end of inserted text. /// @param[out] err Error details, if any -void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err) +void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Arena *arena, + Error *err) FUNC_API_SINCE(6) FUNC_API_TEXTLOCK_ALLOW_CMDWIN { - yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); + yankreg_T reg[1] = { 0 }; VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { - goto cleanup; + return; }); if (lines.size == 0) { - goto cleanup; // Nothing to do. + return; // Nothing to do. } + reg->y_array = arena_alloc(arena, lines.size * sizeof(uint8_t *), true); + reg->y_size = lines.size; for (size_t i = 0; i < lines.size; i++) { VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { - goto cleanup; + return; }); String line = lines.items[i].data.string; - reg->y_array[i] = xmemdupz(line.data, line.size); + reg->y_array[i] = arena_memdupz(arena, line.data, line.size); memchrsub(reg->y_array[i], NUL, NL, line.size); } @@ -1290,10 +1295,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, msg_silent--; VIsual_active = VIsual_was_active; }); - -cleanup: - free_register(reg); - xfree(reg); } /// Subscribes to event broadcasts. @@ -1583,13 +1584,12 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) /// /// @param[out] err Error details, if any void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type, - Dictionary methods, Dictionary attributes, Error *err) + Dictionary methods, Dictionary attributes, Arena *arena, Error *err) FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY { - Dictionary info = ARRAY_DICT_INIT; - PUT(info, "name", copy_object(STRING_OBJ(name), NULL)); + MAXSIZE_TEMP_DICT(info, 5); + PUT_C(info, "name", STRING_OBJ(name)); - version = copy_dictionary(version, NULL); bool has_major = false; for (size_t i = 0; i < version.size; i++) { if (strequal(version.items[i].key.data, "major")) { @@ -1598,15 +1598,21 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, } } if (!has_major) { - PUT(version, "major", INTEGER_OBJ(0)); + Dictionary v = arena_dict(arena, version.size + 1); + if (version.size) { + memcpy(v.items, version.items, version.size * sizeof(v.items[0])); + v.size = version.size; + } + PUT_C(v, "major", INTEGER_OBJ(0)); + version = v; } - PUT(info, "version", DICTIONARY_OBJ(version)); + PUT_C(info, "version", DICTIONARY_OBJ(version)); - PUT(info, "type", copy_object(STRING_OBJ(type), NULL)); - PUT(info, "methods", DICTIONARY_OBJ(copy_dictionary(methods, NULL))); - PUT(info, "attributes", DICTIONARY_OBJ(copy_dictionary(attributes, NULL))); + PUT_C(info, "type", STRING_OBJ(type)); + PUT_C(info, "methods", DICTIONARY_OBJ(methods)); + PUT_C(info, "attributes", DICTIONARY_OBJ(attributes)); - rpc_set_client_info(channel_id, info); + rpc_set_client_info(channel_id, copy_dictionary(info, NULL)); } /// Gets information about a channel. diff --git a/src/nvim/ops.c b/src/nvim/ops.c index f91df49e4f..e7a3aa29aa 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -6499,8 +6499,6 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines) } } - reg->y_array = xcalloc(lines, sizeof(uint8_t *)); - reg->y_size = lines; reg->additional_data = NULL; reg->timestamp = 0; return true; @@ -6513,7 +6511,6 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust) // but otherwise there is no line after the final newline if (reg->y_type != kMTCharWise) { if (reg->y_type == kMTUnknown || clipboard_adjust) { - xfree(reg->y_array[reg->y_size - 1]); reg->y_size--; } if (reg->y_type == kMTUnknown) { diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 44fcc29ad1..fb6397f9eb 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -574,20 +574,20 @@ static int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, return did_one ? OK : FAIL; } -Array runtime_inspect(void) +Array runtime_inspect(Arena *arena) { RuntimeSearchPath path = runtime_search_path; - Array rv = ARRAY_DICT_INIT; + Array rv = arena_array(arena, kv_size(path)); for (size_t i = 0; i < kv_size(path); i++) { SearchPathItem *item = &kv_A(path, i); Array entry = ARRAY_DICT_INIT; - ADD(entry, CSTR_TO_OBJ(item->path)); - ADD(entry, BOOLEAN_OBJ(item->after)); + ADD_C(entry, CSTR_AS_OBJ(item->path)); + ADD_C(entry, BOOLEAN_OBJ(item->after)); if (item->has_lua != kNone) { - ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); + ADD_C(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); } - ADD(rv, ARRAY_OBJ(entry)); + ADD_C(rv, ARRAY_OBJ(entry)); } return rv; } diff --git a/src/nvim/usercmd.c b/src/nvim/usercmd.c index c4e04159ef..8d41edec8a 100644 --- a/src/nvim/usercmd.c +++ b/src/nvim/usercmd.c @@ -1744,25 +1744,24 @@ int do_ucmd(exarg_T *eap, bool preview) /// @param buf Buffer to inspect, or NULL to get global commands. /// /// @return Map of maps describing commands -Dictionary commands_array(buf_T *buf) +Dictionary commands_array(buf_T *buf, Arena *arena) { - Dictionary rv = ARRAY_DICT_INIT; - char str[20]; garray_T *gap = (buf == NULL) ? &ucmds : &buf->b_ucmds; + Dictionary rv = arena_dict(arena, (size_t)gap->ga_len); for (int i = 0; i < gap->ga_len; i++) { char arg[2] = { 0, 0 }; - Dictionary d = ARRAY_DICT_INIT; + Dictionary d = arena_dict(arena, 14); ucmd_T *cmd = USER_CMD_GA(gap, i); - PUT(d, "name", CSTR_TO_OBJ(cmd->uc_name)); - PUT(d, "definition", CSTR_TO_OBJ(cmd->uc_rep)); - PUT(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid)); - PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG))); - PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR))); - PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_REGSTR))); - PUT(d, "keepscript", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_KEEPSCRIPT))); - PUT(d, "preview", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_PREVIEW))); + PUT_C(d, "name", CSTR_AS_OBJ(cmd->uc_name)); + PUT_C(d, "definition", CSTR_AS_OBJ(cmd->uc_rep)); + PUT_C(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid)); + PUT_C(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG))); + PUT_C(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR))); + PUT_C(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_REGSTR))); + PUT_C(d, "keepscript", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_KEEPSCRIPT))); + PUT_C(d, "preview", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_PREVIEW))); switch (cmd->uc_argt & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) { case 0: @@ -1776,49 +1775,47 @@ Dictionary commands_array(buf_T *buf) case (EX_EXTRA | EX_NOSPC | EX_NEEDARG): arg[0] = '1'; break; } - PUT(d, "nargs", CSTR_TO_OBJ(arg)); + PUT_C(d, "nargs", CSTR_TO_ARENA_OBJ(arena, arg)); char *cmd_compl = get_command_complete(cmd->uc_compl); - PUT(d, "complete", (cmd_compl == NULL - ? NIL : CSTR_TO_OBJ(cmd_compl))); - PUT(d, "complete_arg", cmd->uc_compl_arg == NULL - ? NIL : CSTR_TO_OBJ(cmd->uc_compl_arg)); + PUT_C(d, "complete", (cmd_compl == NULL + ? NIL : CSTR_AS_OBJ(cmd_compl))); + PUT_C(d, "complete_arg", cmd->uc_compl_arg == NULL + ? NIL : CSTR_AS_OBJ(cmd->uc_compl_arg)); Object obj = NIL; if (cmd->uc_argt & EX_COUNT) { if (cmd->uc_def >= 0) { - snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); - obj = CSTR_TO_OBJ(str); // -count=N + obj = STRING_OBJ(arena_printf(arena, "%" PRId64, cmd->uc_def)); // -count=N } else { - obj = CSTR_TO_OBJ("0"); // -count + obj = CSTR_AS_OBJ("0"); // -count } } - PUT(d, "count", obj); + PUT_C(d, "count", obj); obj = NIL; if (cmd->uc_argt & EX_RANGE) { if (cmd->uc_argt & EX_DFLALL) { - obj = CSTR_TO_OBJ("%"); // -range=% + obj = STATIC_CSTR_AS_OBJ("%"); // -range=% } else if (cmd->uc_def >= 0) { - snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); - obj = CSTR_TO_OBJ(str); // -range=N + obj = STRING_OBJ(arena_printf(arena, "%" PRId64, cmd->uc_def)); // -range=N } else { - obj = CSTR_TO_OBJ("."); // -range + obj = STATIC_CSTR_AS_OBJ("."); // -range } } - PUT(d, "range", obj); + PUT_C(d, "range", obj); obj = NIL; for (int j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) { if (addr_type_complete[j].expand != ADDR_LINES && addr_type_complete[j].expand == cmd->uc_addr_type) { - obj = CSTR_TO_OBJ(addr_type_complete[j].name); + obj = CSTR_AS_OBJ(addr_type_complete[j].name); break; } } - PUT(d, "addr", obj); + PUT_C(d, "addr", obj); - PUT(rv, cmd->uc_name, DICTIONARY_OBJ(d)); + PUT_C(rv, cmd->uc_name, DICTIONARY_OBJ(d)); } return rv; } |