diff options
Diffstat (limited to 'src/nvim/api')
-rw-r--r-- | src/nvim/api/buffer.c | 15 | ||||
-rw-r--r-- | src/nvim/api/command.c | 32 | ||||
-rw-r--r-- | src/nvim/api/deprecated.c | 32 | ||||
-rw-r--r-- | src/nvim/api/private/converter.c | 95 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 11 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.h | 1 | ||||
-rw-r--r-- | src/nvim/api/tabpage.c | 8 | ||||
-rw-r--r-- | src/nvim/api/ui.c | 8 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 29 | ||||
-rw-r--r-- | src/nvim/api/vimscript.c | 16 | ||||
-rw-r--r-- | src/nvim/api/window.c | 15 |
11 files changed, 139 insertions, 123 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 993e290b2d..110154f8de 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -869,7 +869,7 @@ Integer nvim_buf_get_offset(Buffer buffer, Integer index, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_buf_get_var(Buffer buffer, String name, Error *err) +Object nvim_buf_get_var(Buffer buffer, String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -878,7 +878,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err) return (Object)OBJECT_INIT; } - return dict_get_value(buf->b_vars, name, err); + return dict_get_value(buf->b_vars, name, arena, err); } /// Gets a changed tick of a buffer @@ -957,7 +957,7 @@ void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err) return; } - dict_set_var(buf->b_vars, name, value, false, false, err); + dict_set_var(buf->b_vars, name, value, false, false, NULL, err); } /// Removes a buffer-scoped (b:) variable @@ -974,7 +974,7 @@ void nvim_buf_del_var(Buffer buffer, String name, Error *err) return; } - dict_set_var(buf->b_vars, name, NIL, true, false, err); + dict_set_var(buf->b_vars, name, NIL, true, false, NULL, err); } /// Gets the full file name for the buffer @@ -1175,7 +1175,7 @@ Boolean nvim_buf_set_mark(Buffer buffer, String name, Integer line, Integer col, /// uppercase/file mark set in another buffer. /// @see |nvim_buf_set_mark()| /// @see |nvim_buf_del_mark()| -ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) +ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; @@ -1205,8 +1205,9 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) pos = fm->mark; } - ADD(rv, INTEGER_OBJ(pos.lnum)); - ADD(rv, INTEGER_OBJ(pos.col)); + rv = arena_array(arena, 2); + ADD_C(rv, INTEGER_OBJ(pos.lnum)); + ADD_C(rv, INTEGER_OBJ(pos.col)); return rv; } diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c index 0ac3d42231..a21c9e70a7 100644 --- a/src/nvim/api/command.c +++ b/src/nvim/api/command.c @@ -305,7 +305,7 @@ end: /// - output: (boolean, default false) Whether to return command output. /// @param[out] err Error details, if any. /// @return Command output (non-error, non-shell |:!|) if `output` is true, else empty string. -String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error *err) +String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena *arena, Error *err) FUNC_API_SINCE(10) { exarg_T ea; @@ -343,7 +343,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error goto end; }); - cmdname = string_to_cstr(cmd->cmd); + cmdname = arena_string(arena, cmd->cmd).data; ea.cmd = cmdname; char *p = find_ex_command(&ea, NULL); @@ -352,9 +352,8 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error // autocommands defined, trigger the matching autocommands. if (p != NULL && ea.cmdidx == CMD_SIZE && ASCII_ISUPPER(*ea.cmd) && has_event(EVENT_CMDUNDEFINED)) { - p = xstrdup(cmdname); + p = arena_string(arena, cmd->cmd).data; int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL); - xfree(p); // If the autocommands did something and didn't cause an error, try // finding the command again. p = (ret && !aborting()) ? find_ex_command(&ea, NULL) : ea.cmd; @@ -383,28 +382,31 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error if (HAS_KEY(cmd, cmd, args)) { // Process all arguments. Convert non-String arguments to String and check if String arguments // have non-whitespace characters. + args = arena_array(arena, cmd->args.size); for (size_t i = 0; i < cmd->args.size; i++) { Object elem = cmd->args.items[i]; char *data_str; switch (elem.type) { case kObjectTypeBoolean: - data_str = xcalloc(2, sizeof(char)); + data_str = arena_alloc(arena, 2, false); data_str[0] = elem.data.boolean ? '1' : '0'; data_str[1] = '\0'; + ADD_C(args, CSTR_AS_OBJ(data_str)); break; case kObjectTypeBuffer: case kObjectTypeWindow: case kObjectTypeTabpage: case kObjectTypeInteger: - data_str = xcalloc(NUMBUFLEN, sizeof(char)); + data_str = arena_alloc(arena, NUMBUFLEN, false); snprintf(data_str, NUMBUFLEN, "%" PRId64, elem.data.integer); + ADD_C(args, CSTR_AS_OBJ(data_str)); break; case kObjectTypeString: VALIDATE_EXP(!string_iswhite(elem.data.string), "command arg", "non-whitespace", NULL, { goto end; }); - data_str = string_to_cstr(elem.data.string); + ADD_C(args, elem); break; default: VALIDATE_EXP(false, "command arg", "valid type", api_typename(elem.type), { @@ -412,8 +414,6 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error }); break; } - - ADD(args, CSTR_AS_OBJ(data_str)); } bool argc_valid; @@ -666,26 +666,20 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error } if (opts->output && capture_local.ga_len > 1) { - retv = (String){ - .data = capture_local.ga_data, - .size = (size_t)capture_local.ga_len, - }; + // TODO(bfredl): if there are more cases like this we might want custom xfree-list in arena + retv = CBUF_TO_ARENA_STR(arena, capture_local.ga_data, (size_t)capture_local.ga_len); // redir usually (except :echon) prepends a newline. if (retv.data[0] == '\n') { - memmove(retv.data, retv.data + 1, retv.size - 1); - retv.data[retv.size - 1] = '\0'; - retv.size = retv.size - 1; + retv.data++; + retv.size--; } - goto end; } clear_ga: if (opts->output) { ga_clear(&capture_local); } end: - api_free_array(args); xfree(cmdline); - xfree(cmdname); xfree(ea.args); xfree(ea.arglens); diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index c9a6036b8f..9b8cacd7c2 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -362,7 +362,7 @@ void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean in /// /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. -Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) +Object buffer_set_var(Buffer buffer, String name, Object value, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -371,7 +371,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) return NIL; } - return dict_set_var(buf->b_vars, name, value, false, true, err); + return dict_set_var(buf->b_vars, name, value, false, true, arena, err); } /// Removes a buffer-scoped (b:) variable @@ -382,7 +382,7 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Old value -Object buffer_del_var(Buffer buffer, String name, Error *err) +Object buffer_del_var(Buffer buffer, String name, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -391,7 +391,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) return NIL; } - return dict_set_var(buf->b_vars, name, NIL, true, true, err); + return dict_set_var(buf->b_vars, name, NIL, true, true, arena, err); } /// Sets a window-scoped (w:) variable @@ -406,7 +406,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) /// /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. -Object window_set_var(Window window, String name, Object value, Error *err) +Object window_set_var(Window window, String name, Object value, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -415,7 +415,7 @@ Object window_set_var(Window window, String name, Object value, Error *err) return NIL; } - return dict_set_var(win->w_vars, name, value, false, true, err); + return dict_set_var(win->w_vars, name, value, false, true, arena, err); } /// Removes a window-scoped (w:) variable @@ -426,7 +426,7 @@ Object window_set_var(Window window, String name, Object value, Error *err) /// @param name variable name /// @param[out] err Error details, if any /// @return Old value -Object window_del_var(Window window, String name, Error *err) +Object window_del_var(Window window, String name, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -435,7 +435,7 @@ Object window_del_var(Window window, String name, Error *err) return NIL; } - return dict_set_var(win->w_vars, name, NIL, true, true, err); + return dict_set_var(win->w_vars, name, NIL, true, true, arena, err); } /// Sets a tab-scoped (t:) variable @@ -450,7 +450,7 @@ Object window_del_var(Window window, String name, Error *err) /// /// @warning It may return nil if there was no previous value /// or if previous value was `v:null`. -Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) +Object tabpage_set_var(Tabpage tabpage, String name, Object value, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -459,7 +459,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) return NIL; } - return dict_set_var(tab->tp_vars, name, value, false, true, err); + return dict_set_var(tab->tp_vars, name, value, false, true, arena, err); } /// Removes a tab-scoped (t:) variable @@ -470,7 +470,7 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Old value -Object tabpage_del_var(Tabpage tabpage, String name, Error *err) +Object tabpage_del_var(Tabpage tabpage, String name, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -479,7 +479,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) return NIL; } - return dict_set_var(tab->tp_vars, name, NIL, true, true, err); + return dict_set_var(tab->tp_vars, name, NIL, true, true, arena, err); } /// @deprecated @@ -487,18 +487,18 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) /// @warning May return nil if there was no previous value /// OR if previous value was `v:null`. /// @return Old value or nil if there was no previous value. -Object vim_set_var(String name, Object value, Error *err) +Object vim_set_var(String name, Object value, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { - return dict_set_var(&globvardict, name, value, false, true, err); + return dict_set_var(&globvardict, name, value, false, true, arena, err); } /// @deprecated /// @see nvim_del_var -Object vim_del_var(String name, Error *err) +Object vim_del_var(String name, Arena *arena, Error *err) FUNC_API_DEPRECATED_SINCE(1) { - return dict_set_var(&globvardict, name, NIL, true, true, err); + return dict_set_var(&globvardict, name, NIL, true, true, arena, err); } static int64_t convert_index(int64_t index) diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c index e7b8934c97..a70ef1e50b 100644 --- a/src/nvim/api/private/converter.c +++ b/src/nvim/api/private/converter.c @@ -19,6 +19,8 @@ /// Helper structure for vim_to_object typedef struct { kvec_withinit_t(Object, 2) stack; ///< Object stack. + Arena *arena; ///< arena where objects will be allocated + bool reuse_strdata; } EncodedData; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -41,12 +43,21 @@ typedef struct { #define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \ kvi_push(edata->stack, FLOAT_OBJ((Float)(flt))) +static Object typval_cbuf_to_obj(EncodedData *edata, const char *data, size_t len) +{ + if (edata->reuse_strdata) { + return STRING_OBJ(cbuf_as_string((char *)(len ? data : ""), len)); + } else { + return CBUF_TO_ARENA_OBJ(edata->arena, data, len); + } +} + #define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \ do { \ const size_t len_ = (size_t)(len); \ const char *const str_ = (str); \ assert(len_ == 0 || str_ != NULL); \ - kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_ ? str_ : ""), len_))); \ + kvi_push(edata->stack, typval_cbuf_to_obj(edata, str_, len_)); \ } while (0) #define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING @@ -58,10 +69,7 @@ typedef struct { do { \ const size_t len_ = (size_t)(len); \ const blob_T *const blob_ = (blob); \ - kvi_push(edata->stack, STRING_OBJ(((String) { \ - .data = len_ != 0 ? xmemdupz(blob_->bv_ga.ga_data, len_) : xstrdup(""), \ - .size = len_ \ - }))); \ + kvi_push(edata->stack, typval_cbuf_to_obj(edata, len_ ? blob_->bv_ga.ga_data : "", len_)); \ } while (0) #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ @@ -90,11 +98,7 @@ typedef struct { static inline void typval_encode_list_start(EncodedData *const edata, const size_t len) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL { - kvi_push(edata->stack, ARRAY_OBJ(((Array) { - .capacity = len, - .size = 0, - .items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)), - }))); + kvi_push(edata->stack, ARRAY_OBJ(arena_array(edata->arena, len))); } #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ @@ -109,7 +113,7 @@ static inline void typval_encode_between_list_items(EncodedData *const edata) Object *const list = &kv_last(edata->stack); assert(list->type == kObjectTypeArray); assert(list->data.array.size < list->data.array.capacity); - list->data.array.items[list->data.array.size++] = item; + ADD_C(list->data.array, item); } #define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \ @@ -131,11 +135,7 @@ static inline void typval_encode_list_end(EncodedData *const edata) static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len) FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL { - kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) { - .capacity = len, - .size = 0, - .items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.dictionary.items)), - }))); + kvi_push(edata->stack, DICTIONARY_OBJ(arena_dict(edata->arena, len))); } #define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \ @@ -156,9 +156,8 @@ static inline void typval_encode_after_key(EncodedData *const edata) dict->data.dictionary.items[dict->data.dictionary.size].key = key.data.string; } else { - api_free_object(key); dict->data.dictionary.items[dict->data.dictionary.size].key - = STATIC_CSTR_TO_STRING("__INVALID_KEY__"); + = STATIC_CSTR_AS_STRING("__INVALID_KEY__"); } } @@ -233,17 +232,22 @@ static inline void typval_encode_dict_end(EncodedData *const edata) #undef TYPVAL_ENCODE_CONV_RECURSE #undef TYPVAL_ENCODE_ALLOW_SPECIALS -/// Convert a vim object to an `Object` instance, recursively expanding +/// Convert a vim object to an `Object` instance, recursively converting /// Arrays/Dictionaries. /// /// @param obj The source object +/// @param arena if NULL, use direct allocation +/// @param reuse_strdata when true, don't copy string data to Arena but reference +/// typval strings directly. takes no effect when arena is +/// NULL /// @return The converted value -Object vim_to_object(typval_T *obj) +Object vim_to_object(typval_T *obj, Arena *arena, bool reuse_strdata) { EncodedData edata; kvi_init(edata.stack); - const int evo_ret = encode_vim_to_object(&edata, obj, - "vim_to_object argument"); + edata.arena = arena; + edata.reuse_strdata = reuse_strdata; + const int evo_ret = encode_vim_to_object(&edata, obj, "vim_to_object argument"); (void)evo_ret; assert(evo_ret == OK); Object ret = kv_A(edata.stack, 0); @@ -260,10 +264,18 @@ Object vim_to_object(typval_T *obj) /// @param err Error object. void object_to_vim(Object obj, typval_T *tv, Error *err) { + object_to_vim_take_luaref(&obj, tv, false, err); +} + +/// same as object_to_vim but consumes all luarefs (nested) in `obj` +/// +/// useful when `obj` is allocated on an arena +void object_to_vim_take_luaref(Object *obj, typval_T *tv, bool take_luaref, Error *err) +{ tv->v_type = VAR_UNKNOWN; tv->v_lock = VAR_UNLOCKED; - switch (obj.type) { + switch (obj->type) { case kObjectTypeNil: tv->v_type = VAR_SPECIAL; tv->vval.v_special = kSpecialVarNull; @@ -271,41 +283,40 @@ void object_to_vim(Object obj, typval_T *tv, Error *err) case kObjectTypeBoolean: tv->v_type = VAR_BOOL; - tv->vval.v_bool = obj.data.boolean ? kBoolVarTrue : kBoolVarFalse; + tv->vval.v_bool = obj->data.boolean ? kBoolVarTrue : kBoolVarFalse; break; case kObjectTypeBuffer: case kObjectTypeWindow: case kObjectTypeTabpage: case kObjectTypeInteger: - STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T), + STATIC_ASSERT(sizeof(obj->data.integer) <= sizeof(varnumber_T), "Integer size must be <= Vimscript number size"); tv->v_type = VAR_NUMBER; - tv->vval.v_number = (varnumber_T)obj.data.integer; + tv->vval.v_number = (varnumber_T)obj->data.integer; break; case kObjectTypeFloat: tv->v_type = VAR_FLOAT; - tv->vval.v_float = obj.data.floating; + tv->vval.v_float = obj->data.floating; break; case kObjectTypeString: tv->v_type = VAR_STRING; - if (obj.data.string.data == NULL) { + if (obj->data.string.data == NULL) { tv->vval.v_string = NULL; } else { - tv->vval.v_string = xmemdupz(obj.data.string.data, - obj.data.string.size); + tv->vval.v_string = xmemdupz(obj->data.string.data, + obj->data.string.size); } break; case kObjectTypeArray: { - list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size); + list_T *const list = tv_list_alloc((ptrdiff_t)obj->data.array.size); - for (uint32_t i = 0; i < obj.data.array.size; i++) { - Object item = obj.data.array.items[i]; + for (uint32_t i = 0; i < obj->data.array.size; i++) { typval_T li_tv; - object_to_vim(item, &li_tv, err); + object_to_vim_take_luaref(&obj->data.array.items[i], &li_tv, take_luaref, err); tv_list_append_owned_tv(list, li_tv); } tv_list_ref(list); @@ -318,11 +329,11 @@ void object_to_vim(Object obj, typval_T *tv, Error *err) case kObjectTypeDictionary: { dict_T *const dict = tv_dict_alloc(); - for (uint32_t i = 0; i < obj.data.dictionary.size; i++) { - KeyValuePair item = obj.data.dictionary.items[i]; - String key = item.key; + for (uint32_t i = 0; i < obj->data.dictionary.size; i++) { + KeyValuePair *item = &obj->data.dictionary.items[i]; + String key = item->key; dictitem_T *const di = tv_dict_item_alloc(key.data); - object_to_vim(item.value, &di->di_tv, err); + object_to_vim_take_luaref(&item->value, &di->di_tv, take_luaref, err); tv_dict_add(dict, di); } dict->dv_refcount++; @@ -333,7 +344,13 @@ void object_to_vim(Object obj, typval_T *tv, Error *err) } case kObjectTypeLuaRef: { - char *name = register_luafunc(api_new_luaref(obj.data.luaref)); + LuaRef ref = obj->data.luaref; + if (take_luaref) { + obj->data.luaref = LUA_NOREF; + } else { + ref = api_new_luaref(ref); + } + char *name = register_luafunc(ref); tv->v_type = VAR_FUNC; tv->vval.v_string = xstrdup(name); break; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 7bf0d87603..1446683b0c 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -175,7 +175,7 @@ bool try_end(Error *err) /// @param dict The vimscript dict /// @param key The key /// @param[out] err Details of an error that may have occurred -Object dict_get_value(dict_T *dict, String key, Error *err) +Object dict_get_value(dict_T *dict, String key, Arena *arena, Error *err) { dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); @@ -184,7 +184,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err) return (Object)OBJECT_INIT; } - return vim_to_object(&di->di_tv); + return vim_to_object(&di->di_tv, arena, true); } dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err) @@ -221,7 +221,8 @@ dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err) /// @param retval If true the old value will be converted and returned. /// @param[out] err Details of an error that may have occurred /// @return The old value if `retval` is true and the key was present, else NIL -Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retval, Error *err) +Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retval, Arena *arena, + Error *err) { Object rv = OBJECT_INIT; dictitem_T *di = dict_check_writable(dict, key, del, err); @@ -244,7 +245,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva } // Return the old value if (retval) { - rv = vim_to_object(&di->di_tv); + rv = vim_to_object(&di->di_tv, arena, false); } // Delete the entry tv_dict_item_remove(dict, di); @@ -265,7 +266,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, bool retva } else { // Return the old value if (retval) { - rv = vim_to_object(&di->di_tv); + rv = vim_to_object(&di->di_tv, arena, false); } bool type_error = false; if (dict == &vimvardict diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 11abb8f801..395c5a9d1f 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -35,6 +35,7 @@ #define CSTR_TO_ARENA_STR(arena, s) arena_string(arena, cstr_as_string(s)) #define CSTR_TO_ARENA_OBJ(arena, s) STRING_OBJ(CSTR_TO_ARENA_STR(arena, s)) #define CBUF_TO_ARENA_STR(arena, s, len) arena_string(arena, cbuf_as_string((char *)(s), len)) +#define CBUF_TO_ARENA_OBJ(arena, s, len) STRING_OBJ(CBUF_TO_ARENA_STR(arena, s, len)) #define BUFFER_OBJ(s) ((Object) { \ .type = kObjectTypeBuffer, \ diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index fadc03b3e5..109075df8e 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -49,7 +49,7 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err) +Object nvim_tabpage_get_var(Tabpage tabpage, String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -58,7 +58,7 @@ Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err) return (Object)OBJECT_INIT; } - return dict_get_value(tab->tp_vars, name, err); + return dict_get_value(tab->tp_vars, name, arena, err); } /// Sets a tab-scoped (t:) variable @@ -76,7 +76,7 @@ void nvim_tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err return; } - dict_set_var(tab->tp_vars, name, value, false, false, err); + dict_set_var(tab->tp_vars, name, value, false, false, NULL, err); } /// Removes a tab-scoped (t:) variable @@ -93,7 +93,7 @@ void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err) return; } - dict_set_var(tab->tp_vars, name, NIL, true, false, err); + dict_set_var(tab->tp_vars, name, NIL, true, false, NULL, err); } /// Gets the current window in a tabpage diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index c7280253c2..140b520cb5 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -1029,12 +1029,12 @@ static Array translate_contents(UI *ui, Array contents, Arena *arena) if (attr) { Dictionary rgb_attrs = arena_dict(arena, HLATTRS_DICT_SIZE); hlattrs2dict(&rgb_attrs, NULL, syn_attr2entry(attr), ui->rgb, false); - ADD(new_item, DICTIONARY_OBJ(rgb_attrs)); + ADD_C(new_item, DICTIONARY_OBJ(rgb_attrs)); } else { - ADD(new_item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); + ADD_C(new_item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); } - ADD(new_item, item.items[1]); - ADD(new_contents, ARRAY_OBJ(new_item)); + ADD_C(new_item, item.items[1]); + ADD_C(new_contents, ARRAY_OBJ(new_item)); } return new_contents; } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 769537ac98..b7cb14867d 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -690,7 +690,7 @@ void nvim_del_current_line(Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_get_var(String name, Error *err) +Object nvim_get_var(String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { dictitem_T *di = tv_dict_find(&globvardict, name.data, (ptrdiff_t)name.size); @@ -704,7 +704,7 @@ Object nvim_get_var(String name, Error *err) VALIDATE((di != NULL), "Key not found: %s", name.data, { return (Object)OBJECT_INIT; }); - return vim_to_object(&di->di_tv); + return vim_to_object(&di->di_tv, arena, true); } /// Sets a global (g:) variable. @@ -715,7 +715,7 @@ Object nvim_get_var(String name, Error *err) void nvim_set_var(String name, Object value, Error *err) FUNC_API_SINCE(1) { - dict_set_var(&globvardict, name, value, false, false, err); + dict_set_var(&globvardict, name, value, false, false, NULL, err); } /// Removes a global (g:) variable. @@ -725,7 +725,7 @@ void nvim_set_var(String name, Object value, Error *err) void nvim_del_var(String name, Error *err) FUNC_API_SINCE(1) { - dict_set_var(&globvardict, name, NIL, true, false, err); + dict_set_var(&globvardict, name, NIL, true, false, NULL, err); } /// Gets a v: variable. @@ -733,10 +733,10 @@ void nvim_del_var(String name, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_get_vvar(String name, Error *err) +Object nvim_get_vvar(String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { - return dict_get_value(&vimvardict, name, err); + return dict_get_value(&vimvardict, name, arena, err); } /// Sets a v: variable, if it is not readonly. @@ -747,7 +747,7 @@ Object nvim_get_vvar(String name, Error *err) void nvim_set_vvar(String name, Object value, Error *err) FUNC_API_SINCE(6) { - dict_set_var(&vimvardict, name, value, false, false, err); + dict_set_var(&vimvardict, name, value, false, false, NULL, err); } /// Echo a message. @@ -1370,7 +1370,7 @@ Dictionary nvim_get_color_map(Arena *arena) /// @param[out] err Error details, if any /// /// @return map of global |context|. -Dictionary nvim_get_context(Dict(context) *opts, Error *err) +Dictionary nvim_get_context(Dict(context) *opts, Arena *arena, Error *err) FUNC_API_SINCE(6) { Array types = ARRAY_DICT_INIT; @@ -1406,7 +1406,7 @@ Dictionary nvim_get_context(Dict(context) *opts, Error *err) Context ctx = CONTEXT_INIT; ctx_save(&ctx, int_types); - Dictionary dict = ctx_to_dict(&ctx); + Dictionary dict = ctx_to_dict(&ctx, arena); ctx_free(&ctx); return dict; } @@ -2065,7 +2065,7 @@ Boolean nvim_del_mark(String name, Error *err) /// not set. /// @see |nvim_buf_set_mark()| /// @see |nvim_del_mark()| -Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) +Array nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, Error *err) FUNC_API_SINCE(8) { Array rv = ARRAY_DICT_INIT; @@ -2113,10 +2113,11 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Error *err) col = pos.col; } - ADD(rv, INTEGER_OBJ(row)); - ADD(rv, INTEGER_OBJ(col)); - ADD(rv, INTEGER_OBJ(bufnr)); - ADD(rv, CSTR_TO_OBJ(filename)); + rv = arena_array(arena, 4); + ADD_C(rv, INTEGER_OBJ(row)); + ADD_C(rv, INTEGER_OBJ(col)); + ADD_C(rv, INTEGER_OBJ(bufnr)); + ADD_C(rv, CSTR_TO_ARENA_OBJ(arena, filename)); if (allocated) { xfree(filename); diff --git a/src/nvim/api/vimscript.c b/src/nvim/api/vimscript.c index 56541bb8b8..949356acc6 100644 --- a/src/nvim/api/vimscript.c +++ b/src/nvim/api/vimscript.c @@ -148,7 +148,7 @@ void nvim_command(String command, Error *err) /// @param expr Vimscript expression string /// @param[out] err Error details, if any /// @return Evaluation result or expanded object -Object nvim_eval(String expr, Error *err) +Object nvim_eval(String expr, Arena *arena, Error *err) FUNC_API_SINCE(1) { static int recursive = 0; // recursion depth @@ -179,7 +179,7 @@ Object nvim_eval(String expr, Error *err) api_set_error(err, kErrorTypeException, "Failed to evaluate expression: '%.*s'", 256, expr.data); } else { - rv = vim_to_object(&rettv); + rv = vim_to_object(&rettv, arena, false); } } @@ -196,7 +196,7 @@ Object nvim_eval(String expr, Error *err) /// @param self `self` dict, or NULL for non-dict functions /// @param[out] err Error details, if any /// @return Result of the function call -static Object _call_function(String fn, Array args, dict_T *self, Error *err) +static Object _call_function(String fn, Array args, dict_T *self, Arena *arena, Error *err) { static int recursive = 0; // recursion depth Object rv = OBJECT_INIT; @@ -239,7 +239,7 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) }); if (!ERROR_SET(err)) { - rv = vim_to_object(&rettv); + rv = vim_to_object(&rettv, arena, false); } tv_clear(&rettv); @@ -260,10 +260,10 @@ static Object _call_function(String fn, Array args, dict_T *self, Error *err) /// @param args Function arguments packed in an Array /// @param[out] err Error details, if any /// @return Result of the function call -Object nvim_call_function(String fn, Array args, Error *err) +Object nvim_call_function(String fn, Array args, Arena *arena, Error *err) FUNC_API_SINCE(1) { - return _call_function(fn, args, NULL, err); + return _call_function(fn, args, NULL, arena, err); } /// Calls a Vimscript |Dictionary-function| with the given arguments. @@ -275,7 +275,7 @@ Object nvim_call_function(String fn, Array args, Error *err) /// @param args Function arguments packed in an Array /// @param[out] err Error details, if any /// @return Result of the function call -Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) +Object nvim_call_dict_function(Object dict, String fn, Array args, Arena *arena, Error *err) FUNC_API_SINCE(4) { Object rv = OBJECT_INIT; @@ -337,7 +337,7 @@ Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err) goto end; } - rv = _call_function(fn, args, self_dict, err); + rv = _call_function(fn, args, self_dict, arena, err); end: if (mustfree) { tv_clear(&rettv); diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index 93c9dfa049..ed1ad5b583 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -237,7 +237,7 @@ void nvim_win_set_width(Window window, Integer width, Error *err) /// @param name Variable name /// @param[out] err Error details, if any /// @return Variable value -Object nvim_win_get_var(Window window, String name, Error *err) +Object nvim_win_get_var(Window window, String name, Arena *arena, Error *err) FUNC_API_SINCE(1) { win_T *win = find_window_by_handle(window, err); @@ -246,7 +246,7 @@ Object nvim_win_get_var(Window window, String name, Error *err) return (Object)OBJECT_INIT; } - return dict_get_value(win->w_vars, name, err); + return dict_get_value(win->w_vars, name, arena, err); } /// Sets a window-scoped (w:) variable @@ -264,7 +264,7 @@ void nvim_win_set_var(Window window, String name, Object value, Error *err) return; } - dict_set_var(win->w_vars, name, value, false, false, err); + dict_set_var(win->w_vars, name, value, false, false, NULL, err); } /// Removes a window-scoped (w:) variable @@ -281,7 +281,7 @@ void nvim_win_del_var(Window window, String name, Error *err) return; } - dict_set_var(win->w_vars, name, NIL, true, false, err); + dict_set_var(win->w_vars, name, NIL, true, false, NULL, err); } /// Gets the window position in display cells. First position is zero. @@ -289,15 +289,16 @@ void nvim_win_del_var(Window window, String name, Error *err) /// @param window Window handle, or 0 for current window /// @param[out] err Error details, if any /// @return (row, col) tuple with the window position -ArrayOf(Integer, 2) nvim_win_get_position(Window window, Error *err) +ArrayOf(Integer, 2) nvim_win_get_position(Window window, Arena *arena, Error *err) FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; win_T *win = find_window_by_handle(window, err); if (win) { - ADD(rv, INTEGER_OBJ(win->w_winrow)); - ADD(rv, INTEGER_OBJ(win->w_wincol)); + rv = arena_array(arena, 2); + ADD_C(rv, INTEGER_OBJ(win->w_winrow)); + ADD_C(rv, INTEGER_OBJ(win->w_wincol)); } return rv; |