Skip to content

Commit

Permalink
Merge pull request neovim#29358 from bfredl/typvalpack
Browse files Browse the repository at this point in the history
refactor(typval): don't use msgpack_packer for msgpackdump()
  • Loading branch information
bfredl committed Jun 24, 2024
2 parents da4e8dc + 2bb1a18 commit 0a789a8
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 109 deletions.
2 changes: 2 additions & 0 deletions src/nvim/api/private/converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef struct {
#endif

#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CHECK_BEFORE

#define TYPVAL_ENCODE_CONV_NIL(tv) \
kvi_push(edata->stack, NIL)
Expand Down Expand Up @@ -217,6 +218,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
Expand Down
76 changes: 25 additions & 51 deletions src/nvim/eval/encode.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <string.h>

#include "klib/kvec.h"
#include "msgpack/pack.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii_defs.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
Expand All @@ -28,6 +28,7 @@
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/msgpack_rpc/packer.h"
#include "nvim/strings.h"
#include "nvim/types_defs.h"
#include "nvim/vim_defs.h" // For _()
Expand Down Expand Up @@ -412,6 +413,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
ga_concat(gap, "{}")

#define TYPVAL_ENCODE_CHECK_BEFORE

#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "v:null")

Expand Down Expand Up @@ -536,6 +539,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#define TYPVAL_ENCODE_ALLOW_SPECIALS true

#define TYPVAL_ENCODE_CHECK_BEFORE

#undef TYPVAL_ENCODE_CONV_NIL
#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "null")
Expand Down Expand Up @@ -821,6 +826,7 @@ bool encode_check_json_key(const typval_T *const tv)
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
Expand Down Expand Up @@ -913,52 +919,22 @@ char *encode_tv2json(typval_T *tv, size_t *len)
}

#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
if ((buf) == NULL) { \
msgpack_pack_bin(packer, 0); \
} else { \
const size_t len_ = (len); \
msgpack_pack_bin(packer, len_); \
msgpack_pack_bin_body(packer, buf, len_); \
} \
} while (0)
mpack_bin(buf, (len), packer); \

#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
do { \
if ((buf) == NULL) { \
msgpack_pack_str(packer, 0); \
} else { \
const size_t len_ = (len); \
msgpack_pack_str(packer, len_); \
msgpack_pack_str_body(packer, buf, len_); \
} \
} while (0)
mpack_str(cbuf_as_string(buf, (len)), packer); \

#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
if ((buf) == NULL) { \
msgpack_pack_ext(packer, 0, (int8_t)(type)); \
} else { \
const size_t len_ = (len); \
msgpack_pack_ext(packer, len_, (int8_t)(type)); \
msgpack_pack_ext_body(packer, buf, len_); \
} \
} while (0)
mpack_ext(buf, (len), (int8_t)(type), packer); \

#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
do { \
const size_t len_ = (size_t)(len); \
msgpack_pack_bin(packer, len_); \
if (len_ > 0) { \
msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \
} \
} while (0)
mpack_bin((blob) ? (blob)->bv_ga.ga_data : NULL, (size_t)(len), packer); \

#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
msgpack_pack_int64(packer, (int64_t)(num))
mpack_integer(&packer->ptr, (Integer)(num))

#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
msgpack_pack_double(packer, (double)(flt))
mpack_float8(&packer->ptr, (double)(flt))

#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
return conv_error(_("E5004: Error while dumping %s, %s: " \
Expand All @@ -970,33 +946,30 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)

#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
msgpack_pack_array(packer, 0)
mpack_array(&packer->ptr, 0)

#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
msgpack_pack_array(packer, (size_t)(len))
mpack_array(&packer->ptr, (uint32_t)(len))

#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)

#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
msgpack_pack_map(packer, 0)
mpack_map(&packer->ptr, 0)

#define TYPVAL_ENCODE_CHECK_BEFORE \
mpack_check_buffer(packer)

#define TYPVAL_ENCODE_CONV_NIL(tv) \
msgpack_pack_nil(packer)
mpack_nil(&packer->ptr)

#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
do { \
if (num) { \
msgpack_pack_true(packer); \
} else { \
msgpack_pack_false(packer); \
} \
} while (0)
mpack_bool(&packer->ptr, (bool)num); \

#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
msgpack_pack_uint64(packer, (num))
mpack_uint64(&packer->ptr, (num))

#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
msgpack_pack_map(packer, (size_t)(len))
mpack_map(&packer->ptr, (uint32_t)(len))

#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)

Expand All @@ -1021,7 +994,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)

#define TYPVAL_ENCODE_SCOPE
#define TYPVAL_ENCODE_NAME msgpack
#define TYPVAL_ENCODE_FIRST_ARG_TYPE msgpack_packer *const
#define TYPVAL_ENCODE_FIRST_ARG_TYPE PackerBuffer *const
#define TYPVAL_ENCODE_FIRST_ARG_NAME packer
#include "nvim/eval/typval_encode.c.h"
#undef TYPVAL_ENCODE_SCOPE
Expand All @@ -1043,6 +1016,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
Expand Down
3 changes: 2 additions & 1 deletion src/nvim/eval/encode.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "nvim/eval/typval_defs.h"
#include "nvim/garray_defs.h"
#include "nvim/msgpack_rpc/packer_defs.h"

/// Convert Vimscript value to msgpack string
///
Expand All @@ -13,7 +14,7 @@
/// @param[in] objname Object name, used for error message.
///
/// @return OK in case of success, FAIL otherwise.
int encode_vim_to_msgpack(msgpack_packer *packer, typval_T *tv, const char *objname);
int encode_vim_to_msgpack(PackerBuffer *packer, typval_T *tv, const char *objname);

/// Convert Vimscript value to :echo output
///
Expand Down
24 changes: 13 additions & 11 deletions src/nvim/eval/funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
#include "nvim/move.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/msgpack_rpc/packer.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/normal.h"
#include "nvim/normal_defs.h"
Expand Down Expand Up @@ -5501,27 +5502,28 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
return;
}
list_T *const list = argvars[0].vval.v_list;
msgpack_packer *packer;
if (argvars[1].v_type != VAR_UNKNOWN
&& strequal(tv_get_string(&argvars[1]), "B")) {
tv_blob_alloc_ret(rettv);
packer = msgpack_packer_new(rettv->vval.v_blob, &encode_blob_write);
} else {
packer = msgpack_packer_new(tv_list_alloc_ret(rettv, kListLenMayKnow),
&encode_list_write);
}
PackerBuffer packer = packer_string_buffer();
const char *const msg = _("msgpackdump() argument, index %i");
// Assume that translation will not take more then 4 times more space
char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN];
int idx = 0;
TV_LIST_ITER(list, li, {
vim_snprintf(msgbuf, sizeof(msgbuf), msg, idx);
idx++;
if (encode_vim_to_msgpack(packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
if (encode_vim_to_msgpack(&packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
break;
}
});
msgpack_packer_free(packer);
String data = packer_take_string(&packer);
if (argvars[1].v_type != VAR_UNKNOWN && strequal(tv_get_string(&argvars[1]), "B")) {
blob_T *b = tv_blob_alloc_ret(rettv);
b->bv_ga.ga_data = data.data;
b->bv_ga.ga_len = (int)data.size;
b->bv_ga.ga_maxlen = (int)(packer.endptr - packer.startptr);
} else {
encode_list_write(tv_list_alloc_ret(rettv, kListLenMayKnow), data.data, data.size);
api_free_string(data);
}
}

static int msgpackparse_convert_item(const msgpack_object data, const msgpack_unpack_return result,
Expand Down
8 changes: 5 additions & 3 deletions src/nvim/eval/typval.c
Original file line number Diff line number Diff line change
Expand Up @@ -3064,8 +3064,7 @@ void f_blob2list(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// list2blob() function
void f_list2blob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
tv_blob_alloc_ret(rettv);
blob_T *const blob = rettv->vval.v_blob;
blob_T *blob = tv_blob_alloc_ret(rettv);

if (tv_check_for_list_arg(argvars, 0) == FAIL) {
return;
Expand Down Expand Up @@ -3252,11 +3251,12 @@ void tv_dict_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg)
/// Also sets reference count.
///
/// @param[out] ret_tv Structure where blob is saved.
void tv_blob_alloc_ret(typval_T *const ret_tv)
blob_T *tv_blob_alloc_ret(typval_T *const ret_tv)
FUNC_ATTR_NONNULL_ALL
{
blob_T *const b = tv_blob_alloc();
tv_blob_set_ret(ret_tv, b);
return b;
}

/// Copy a blob typval to a different typval.
Expand Down Expand Up @@ -3284,6 +3284,7 @@ void tv_blob_copy(blob_T *const from, typval_T *const to)

//{{{3 Clear
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
#define TYPVAL_ENCODE_CHECK_BEFORE

#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
Expand Down Expand Up @@ -3500,6 +3501,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dic
#undef TYPVAL_ENCODE_FIRST_ARG_NAME

#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_NUMBER
Expand Down
7 changes: 7 additions & 0 deletions src/nvim/eval/typval_encode.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
/// something else. For these macros to work the following macros must be
/// defined:

/// @def TYPVAL_ENCODE_CHECK_BEFORE
/// @brief Macro used before any specific CONV function
///
/// can be used for a common check, like flushing a buffer if necessary

/// @def TYPVAL_ENCODE_CONV_NIL
/// @brief Macros used to convert NIL value
///
Expand Down Expand Up @@ -323,6 +328,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack,
MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname)
{
TYPVAL_ENCODE_CHECK_BEFORE;
switch (tv->v_type) {
case VAR_STRING:
TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
Expand Down Expand Up @@ -420,6 +426,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
break;
}
}
TYPVAL_ENCODE_CHECK_BEFORE;
if (i == ARRAY_SIZE(eval_msgpack_type_lists)) {
goto _convert_one_value_regular_dict;
}
Expand Down
3 changes: 3 additions & 0 deletions src/nvim/lua/converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ static bool typval_conv_special = false;

#define TYPVAL_ENCODE_ALLOW_SPECIALS true

#define TYPVAL_ENCODE_CHECK_BEFORE

#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
if (typval_conv_special) { \
Expand Down Expand Up @@ -574,6 +576,7 @@ static bool typval_conv_special = false;
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
Expand Down
Loading

0 comments on commit 0a789a8

Please sign in to comment.