eval: Make sure that copyID is reset when needed

Works by making value pushed on stack represent the exhausted list.

Fixes #5901, except for dictionaries which need similar adjustment.
This commit is contained in:
ZyX 2017-01-07 15:15:14 +03:00
parent 7d0a892b37
commit a970c1a957
4 changed files with 29 additions and 6 deletions

View File

@ -387,6 +387,8 @@ static inline void typval_encode_list_start(EncodedData *const edata,
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
typval_encode_list_start(edata, (size_t)(len)) typval_encode_list_start(edata, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
static inline void typval_encode_between_list_items(EncodedData *const edata) static inline void typval_encode_between_list_items(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{ {
@ -499,6 +501,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#undef TYPVAL_ENCODE_CONV_FUNC_END #undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST #undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START #undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT #undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL #undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL #undef TYPVAL_ENCODE_CONV_BOOL

View File

@ -19147,23 +19147,25 @@ static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
} \ } \
} while (0) } while (0)
static inline int _nothing_conv_list_start(typval_T *const tv) static inline int _nothing_conv_real_list_after_start(
typval_T *const tv, MPConvStackVal *const mpsv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
{ {
if (tv == NULL) { assert(tv != NULL);
return NOTDONE;
}
tv->v_lock = VAR_UNLOCKED; tv->v_lock = VAR_UNLOCKED;
if (tv->vval.v_list->lv_refcount > 1) { if (tv->vval.v_list->lv_refcount > 1) {
tv->vval.v_list->lv_refcount--; tv->vval.v_list->lv_refcount--;
tv->vval.v_list = NULL; tv->vval.v_list = NULL;
mpsv->data.l.li = NULL;
return OK; return OK;
} }
return NOTDONE; return NOTDONE;
} }
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ #define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
do { \ do { \
if (_nothing_conv_list_start(tv) != NOTDONE) { \ if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
goto typval_encode_stop_converting_one_item; \ goto typval_encode_stop_converting_one_item; \
} \ } \
} while (0) } while (0)
@ -19253,6 +19255,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST #undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT #undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_LIST_START #undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS #undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_LIST_END #undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_DICT_START #undef TYPVAL_ENCODE_CONV_DICT_START

View File

@ -369,6 +369,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
ga_append(gap, '[') ga_append(gap, '[')
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ #define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
ga_concat(gap, "{}") ga_concat(gap, "{}")
@ -789,6 +791,7 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_CONV_FUNC_END #undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST #undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START #undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT #undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL #undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL #undef TYPVAL_ENCODE_CONV_BOOL
@ -933,6 +936,8 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \ #define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
msgpack_pack_array(packer, (size_t)(len)) msgpack_pack_array(packer, (size_t)(len))
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \ #define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
msgpack_pack_map(packer, 0) msgpack_pack_map(packer, 0)
@ -994,6 +999,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#undef TYPVAL_ENCODE_CONV_FUNC_END #undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST #undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START #undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT #undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL #undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL #undef TYPVAL_ENCODE_CONV_BOOL

View File

@ -129,6 +129,16 @@
/// point to a special dictionary. /// point to a special dictionary.
/// @param len List length. Is an expression which evaluates to an integer. /// @param len List length. Is an expression which evaluates to an integer.
/// @def TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
/// @brief Macros used after pushing list onto the stack
///
/// Only used for real list_T* lists, not for special dictionaries or partial
/// arguments.
///
/// @param tv Pointer to typval where value is stored. May be NULL. May
/// point to a special dictionary.
/// @param mpsv Pushed MPConvStackVal value.
/// @def TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS /// @def TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
/// @brief Macros used after finishing converting non-last list item /// @brief Macros used after finishing converting non-last list item
/// ///
@ -354,6 +364,7 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}, },
}, },
})); }));
TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
break; break;
} }
case VAR_SPECIAL: { case VAR_SPECIAL: {