diff options
author | ZyX <kp-pav@yandex.ru> | 2017-01-06 22:48:50 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-01-06 22:48:50 +0300 |
commit | 6584fb723ad9fcdc96bbefdf79c638b840bc5655 (patch) | |
tree | 02ff9a13338ec993c9529eab85df93765ce91519 /src | |
parent | 7f11ec00fd483b70d463de5f7661966ffc10a5d1 (diff) | |
download | rneovim-6584fb723ad9fcdc96bbefdf79c638b840bc5655.tar.gz rneovim-6584fb723ad9fcdc96bbefdf79c638b840bc5655.tar.bz2 rneovim-6584fb723ad9fcdc96bbefdf79c638b840bc5655.zip |
eval/typval_encode: Use TYPVAL_ENCODE_CONV_EMPTY_DICT for partials
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/private/helpers.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 11 | ||||
-rw-r--r-- | src/nvim/eval/encode.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/typval_encode.c.h | 50 |
4 files changed, 40 insertions, 27 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index d3564b4ede..701a1cbf2b 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -369,7 +369,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) #define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \ kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 }))) -#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \ +#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ kv_push(edata->stack, \ DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 }))) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ac00d04630..e31e3118fa 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19127,11 +19127,14 @@ static inline void _nothing_conv_func_end(typval_T *const tv) tv->v_lock = VAR_UNLOCKED; \ } while (0) -#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \ +#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ do { \ - dict_unref(tv->vval.v_dict); \ - tv->vval.v_dict = NULL; \ - tv->v_lock = VAR_UNLOCKED; \ + assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \ + dict_unref((dict_T *)dict); \ + *((dict_T **)&dict) = NULL; \ + if (tv != NULL) { \ + ((typval_T *)tv)->v_lock = VAR_UNLOCKED; \ + } \ } while (0) static inline int _nothing_conv_list_start(typval_T *const tv) diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index e3fd857529..071fbc3923 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -369,7 +369,7 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ ga_append(gap, '[') -#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \ +#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ ga_concat(gap, "{}") #define TYPVAL_ENCODE_CONV_NIL(tv) \ @@ -933,7 +933,7 @@ char *encode_tv2json(typval_T *tv, size_t *len) #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ msgpack_pack_array(packer, (size_t)(len)) -#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv) \ +#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ msgpack_pack_map(packer, 0) #define TYPVAL_ENCODE_CONV_NIL(tv) \ diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 5795d339f0..668bdfb26a 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -117,8 +117,10 @@ /// @def TYPVAL_ENCODE_CONV_EMPTY_DICT /// @brief Macros used to convert an empty dictionary /// -/// @param tv Pointer to typval where value is stored. May not be NULL. May +/// @param tv Pointer to typval where value is stored. May be NULL. May /// point to a special dictionary. +/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR +/// (for dictionaries represented as special lists). /// @def TYPVAL_ENCODE_CONV_LIST_START /// @brief Macros used before starting to convert non-empty list @@ -142,7 +144,7 @@ /// /// @param tv Pointer to typval where dictionary is stored. May be NULL. May /// point to a special dictionary. -/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR +/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR /// (for dictionaries represented as special lists). /// @param len Dictionary length. Is an expression which evaluates to an /// integer. @@ -158,7 +160,7 @@ /// /// @param tv Pointer to typval where dictionary is stored. May be NULL. May /// point to a special dictionary. -/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR +/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR /// (for dictionaries represented as special lists). /// @def TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS @@ -166,7 +168,7 @@ /// /// @param tv Pointer to typval where dictionary is stored. May be NULL. May /// point to a special dictionary. -/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR +/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR /// (for dictionaries represented as special lists). /// @def TYPVAL_ENCODE_CONV_DICT_END @@ -174,7 +176,7 @@ /// /// @param tv Pointer to typval where dictionary is stored. May be NULL. May /// point to a special dictionary. -/// @param dict Converted dictionary, lvalue or &#TYPVAL_ENCODE_NODICT_VAR +/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR /// (for dictionaries represented as special lists). /// @def TYPVAL_ENCODE_CONV_RECURSE @@ -224,6 +226,10 @@ #include "nvim/func_attr.h" #include "nvim/eval/typval_encode.h" +/// Dummy variable used because some macros need lvalue +/// +/// Must not be written to, if needed one must check that address of the +/// macros argument is (not) equal to `&TYPVAL_ENCODE_NODICT_VAR`. const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL; static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( @@ -367,7 +373,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( case VAR_DICT: { if (tv->vval.v_dict == NULL || tv->vval.v_dict->dv_hashtab.ht_used == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(tv); + TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict); break; } const dictitem_T *type_di; @@ -490,7 +496,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( } list_T *const val_list = val_di->di_tv.vval.v_list; if (val_list == NULL || val_list->lv_len == 0) { - TYPVAL_ENCODE_CONV_EMPTY_DICT(tv); + TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, TYPVAL_ENCODE_NODICT_VAR); break; } for (const listitem_T *li = val_list->lv_first; li != NULL; @@ -708,20 +714,24 @@ typval_encode_stop_converting_one_item: continue; } } - TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, - dict->dv_hashtab.ht_used); - _mp_push(mpstack, ((MPConvStackVal) { - .type = kMPConvDict, - .tv = NULL, - .data = { - .d = { - .dict = dict, - .dictp = &pt->pt_dict, - .hi = dict->dv_hashtab.ht_array, - .todo = dict->dv_hashtab.ht_used, + if (dict->dv_hashtab.ht_used == 0) { + TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict); + } else { + TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict, + dict->dv_hashtab.ht_used); + _mp_push(mpstack, ((MPConvStackVal) { + .type = kMPConvDict, + .tv = NULL, + .data = { + .d = { + .dict = dict, + .dictp = &pt->pt_dict, + .hi = dict->dv_hashtab.ht_array, + .todo = dict->dv_hashtab.ht_used, + }, }, - }, - })); + })); + } } else { TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1); } |