mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #15509 from bfredl/miniperf
perf(api): avoid spurious allocations when converting small objects
This commit is contained in:
commit
636ecd0c3b
@ -29,7 +29,7 @@ set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua)
|
|||||||
set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua)
|
set(GENERATOR_C_GRAMMAR ${GENERATOR_DIR}/c_grammar.lua)
|
||||||
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
|
set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
|
||||||
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
|
set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
|
||||||
set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c)
|
set(LUA_API_C_BINDINGS ${GENERATED_DIR}/lua_api_c_bindings.generated.c)
|
||||||
set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
|
set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
|
||||||
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
|
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
|
||||||
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
|
set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
|
||||||
@ -305,11 +305,11 @@ add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
|
|||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
|
OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
|
||||||
${API_METADATA} ${MSGPACK_LUA_C_BINDINGS}
|
${API_METADATA} ${LUA_API_C_BINDINGS}
|
||||||
COMMAND ${LUA_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
|
COMMAND ${LUA_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
|
||||||
${GENERATED_API_DISPATCH}
|
${GENERATED_API_DISPATCH}
|
||||||
${GENERATED_FUNCS_METADATA} ${API_METADATA}
|
${GENERATED_FUNCS_METADATA} ${API_METADATA}
|
||||||
${MSGPACK_LUA_C_BINDINGS}
|
${LUA_API_C_BINDINGS}
|
||||||
${API_HEADERS}
|
${API_HEADERS}
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${API_HEADERS}
|
${API_HEADERS}
|
||||||
@ -333,7 +333,7 @@ add_custom_command(
|
|||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND NVIM_GENERATED_SOURCES
|
list(APPEND NVIM_GENERATED_SOURCES
|
||||||
"${MSGPACK_LUA_C_BINDINGS}"
|
"${LUA_API_C_BINDINGS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
/// Helper structure for vim_to_object
|
/// Helper structure for vim_to_object
|
||||||
typedef struct {
|
typedef struct {
|
||||||
kvec_t(Object) stack; ///< Object stack.
|
kvec_withinit_t(Object, 2) stack; ///< Object stack.
|
||||||
} EncodedData;
|
} EncodedData;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
@ -418,28 +418,25 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
|||||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||||
kv_push(edata->stack, NIL)
|
kvi_push(edata->stack, NIL)
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
|
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
|
||||||
kv_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
|
kvi_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
|
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
|
||||||
kv_push(edata->stack, INTEGER_OBJ((Integer)(num)))
|
kvi_push(edata->stack, INTEGER_OBJ((Integer)(num)))
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
|
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
|
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
|
||||||
kv_push(edata->stack, FLOAT_OBJ((Float)(flt)))
|
kvi_push(edata->stack, FLOAT_OBJ((Float)(flt)))
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
|
#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
|
||||||
do { \
|
do { \
|
||||||
const size_t len_ = (size_t)(len); \
|
const size_t len_ = (size_t)(len); \
|
||||||
const char *const str_ = (const char *)(str); \
|
const char *const str_ = (const char *)(str); \
|
||||||
assert(len_ == 0 || str_ != NULL); \
|
assert(len_ == 0 || str_ != NULL); \
|
||||||
kv_push(edata->stack, STRING_OBJ(((String) { \
|
kvi_push(edata->stack, STRING_OBJ(cbuf_to_string((len_?str_:""), len_))); \
|
||||||
.data = xmemdupz((len_?str_:""), len_), \
|
|
||||||
.size = len_ \
|
|
||||||
}))); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
|
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
|
||||||
@ -458,17 +455,17 @@ void set_option_to(uint64_t channel_id, void *to, int type,
|
|||||||
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
|
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
|
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
|
||||||
kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
|
kvi_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
|
||||||
|
|
||||||
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
|
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
|
||||||
kv_push(edata->stack, \
|
kvi_push(edata->stack, \
|
||||||
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
|
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
|
||||||
|
|
||||||
static inline void typval_encode_list_start(EncodedData *const edata,
|
static inline void typval_encode_list_start(EncodedData *const edata,
|
||||||
const size_t len)
|
const size_t len)
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
kv_push(edata->stack, ARRAY_OBJ(((Array) {
|
kvi_push(edata->stack, ARRAY_OBJ(((Array) {
|
||||||
.capacity = len,
|
.capacity = len,
|
||||||
.size = 0,
|
.size = 0,
|
||||||
.items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)),
|
.items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)),
|
||||||
@ -510,7 +507,7 @@ static inline void typval_encode_dict_start(EncodedData *const edata,
|
|||||||
const size_t len)
|
const size_t len)
|
||||||
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
kv_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
|
kvi_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
|
||||||
.capacity = len,
|
.capacity = len,
|
||||||
.size = 0,
|
.size = 0,
|
||||||
.items = xmalloc(len * sizeof(
|
.items = xmalloc(len * sizeof(
|
||||||
@ -618,14 +615,15 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
|
|||||||
/// @return The converted value
|
/// @return The converted value
|
||||||
Object vim_to_object(typval_T *obj)
|
Object vim_to_object(typval_T *obj)
|
||||||
{
|
{
|
||||||
EncodedData edata = { .stack = KV_INITIAL_VALUE };
|
EncodedData edata;
|
||||||
|
kvi_init(edata.stack);
|
||||||
const int evo_ret = encode_vim_to_object(&edata, obj,
|
const int evo_ret = encode_vim_to_object(&edata, obj,
|
||||||
"vim_to_object argument");
|
"vim_to_object argument");
|
||||||
(void)evo_ret;
|
(void)evo_ret;
|
||||||
assert(evo_ret == OK);
|
assert(evo_ret == OK);
|
||||||
Object ret = kv_A(edata.stack, 0);
|
Object ret = kv_A(edata.stack, 0);
|
||||||
assert(kv_size(edata.stack) == 1);
|
assert(kv_size(edata.stack) == 1);
|
||||||
kv_destroy(edata.stack);
|
kvi_destroy(edata.stack);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ if arg[1] == '--help' then
|
|||||||
print(' 2: dispatch output file (dispatch_wrappers.generated.h)')
|
print(' 2: dispatch output file (dispatch_wrappers.generated.h)')
|
||||||
print(' 3: functions metadata output file (funcs_metadata.generated.h)')
|
print(' 3: functions metadata output file (funcs_metadata.generated.h)')
|
||||||
print(' 4: API metadata output file (api_metadata.mpack)')
|
print(' 4: API metadata output file (api_metadata.mpack)')
|
||||||
print(' 5: lua C bindings output file (msgpack_lua_c_bindings.generated.c)')
|
print(' 5: lua C bindings output file (lua_api_c_bindings.generated.c)')
|
||||||
print(' rest: C files where API functions are defined')
|
print(' rest: C files where API functions are defined')
|
||||||
end
|
end
|
||||||
assert(#arg >= 4)
|
assert(#arg >= 4)
|
||||||
@ -378,7 +378,7 @@ output:write('\n')
|
|||||||
local lua_c_functions = {}
|
local lua_c_functions = {}
|
||||||
|
|
||||||
local function process_function(fn)
|
local function process_function(fn)
|
||||||
local lua_c_function_name = ('nlua_msgpack_%s'):format(fn.name)
|
local lua_c_function_name = ('nlua_api_%s'):format(fn.name)
|
||||||
write_shifted_output(output, string.format([[
|
write_shifted_output(output, string.format([[
|
||||||
|
|
||||||
static int %s(lua_State *lstate)
|
static int %s(lua_State *lstate)
|
||||||
|
@ -196,8 +196,9 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
const int initial_size = lua_gettop(lstate);
|
const int initial_size = lua_gettop(lstate);
|
||||||
kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE;
|
kvec_withinit_t(TVPopStackItem, 2) stack = KV_INITIAL_VALUE;
|
||||||
kv_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
|
kvi_init(stack);
|
||||||
|
kvi_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
|
||||||
while (ret && kv_size(stack)) {
|
while (ret && kv_size(stack)) {
|
||||||
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
|
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
|
||||||
emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
|
emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
|
||||||
@ -234,7 +235,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
tv_list_append_owned_tv(kv_pair, (typval_T) {
|
tv_list_append_owned_tv(kv_pair, (typval_T) {
|
||||||
.v_type = VAR_UNKNOWN,
|
.v_type = VAR_UNKNOWN,
|
||||||
});
|
});
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
|
tv_list_append_list(cur.tv->vval.v_list, kv_pair);
|
||||||
cur = (TVPopStackItem) {
|
cur = (TVPopStackItem) {
|
||||||
.tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
|
.tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
|
||||||
@ -247,7 +248,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
|
if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
|
cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -265,7 +266,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
|
tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
|
||||||
.v_type = VAR_UNKNOWN,
|
.v_type = VAR_UNKNOWN,
|
||||||
});
|
});
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
// TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
|
// TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
|
||||||
cur = (TVPopStackItem) {
|
cur = (TVPopStackItem) {
|
||||||
.tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
|
.tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
|
||||||
@ -343,7 +344,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
if (table_props.maxidx != 0) {
|
if (table_props.maxidx != 0) {
|
||||||
cur.container = true;
|
cur.container = true;
|
||||||
cur.idx = lua_gettop(lstate);
|
cur.idx = lua_gettop(lstate);
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -373,7 +374,7 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
|
|||||||
}
|
}
|
||||||
cur.container = true;
|
cur.container = true;
|
||||||
cur.idx = lua_gettop(lstate);
|
cur.idx = lua_gettop(lstate);
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
lua_pushnil(lstate);
|
lua_pushnil(lstate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -434,7 +435,7 @@ nlua_pop_typval_table_processing_end:
|
|||||||
lua_pop(lstate, 1);
|
lua_pop(lstate, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_destroy(stack);
|
kvi_destroy(stack);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
tv_clear(ret_tv);
|
tv_clear(ret_tv);
|
||||||
*ret_tv = (typval_T) {
|
*ret_tv = (typval_T) {
|
||||||
@ -1060,15 +1061,16 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
|
|||||||
{
|
{
|
||||||
Object ret = NIL;
|
Object ret = NIL;
|
||||||
const int initial_size = lua_gettop(lstate);
|
const int initial_size = lua_gettop(lstate);
|
||||||
kvec_t(ObjPopStackItem) stack = KV_INITIAL_VALUE;
|
kvec_withinit_t(ObjPopStackItem, 2) stack = KV_INITIAL_VALUE;
|
||||||
kv_push(stack, ((ObjPopStackItem) { &ret, false }));
|
kvi_init(stack);
|
||||||
|
kvi_push(stack, ((ObjPopStackItem) { &ret, false }));
|
||||||
while (!ERROR_SET(err) && kv_size(stack)) {
|
while (!ERROR_SET(err) && kv_size(stack)) {
|
||||||
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
|
|
||||||
api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ObjPopStackItem cur = kv_pop(stack);
|
ObjPopStackItem cur = kv_pop(stack);
|
||||||
if (cur.container) {
|
if (cur.container) {
|
||||||
|
if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
|
||||||
|
api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (cur.obj->type == kObjectTypeDictionary) {
|
if (cur.obj->type == kObjectTypeDictionary) {
|
||||||
// stack: …, dict, key
|
// stack: …, dict, key
|
||||||
if (cur.obj->data.dictionary.size
|
if (cur.obj->data.dictionary.size
|
||||||
@ -1095,7 +1097,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
|
|||||||
.data = xmemdupz(s, len),
|
.data = xmemdupz(s, len),
|
||||||
.size = len,
|
.size = len,
|
||||||
};
|
};
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
cur = (ObjPopStackItem) {
|
cur = (ObjPopStackItem) {
|
||||||
.obj = &cur.obj->data.dictionary.items[idx].value,
|
.obj = &cur.obj->data.dictionary.items[idx].value,
|
||||||
.container = false,
|
.container = false,
|
||||||
@ -1117,7 +1119,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
|
|||||||
lua_pop(lstate, 2);
|
lua_pop(lstate, 2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
cur = (ObjPopStackItem) {
|
cur = (ObjPopStackItem) {
|
||||||
.obj = &cur.obj->data.array.items[idx],
|
.obj = &cur.obj->data.array.items[idx],
|
||||||
.container = false,
|
.container = false,
|
||||||
@ -1169,7 +1171,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
|
|||||||
sizeof(cur.obj->data.array.items[0]));
|
sizeof(cur.obj->data.array.items[0]));
|
||||||
cur.obj->data.array.capacity = table_props.maxidx;
|
cur.obj->data.array.capacity = table_props.maxidx;
|
||||||
cur.container = true;
|
cur.container = true;
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1185,7 +1187,7 @@ Object nlua_pop_Object(lua_State *const lstate, bool ref, Error *const err)
|
|||||||
sizeof(cur.obj->data.dictionary.items[0]));
|
sizeof(cur.obj->data.dictionary.items[0]));
|
||||||
cur.obj->data.dictionary.capacity = table_props.string_keys_num;
|
cur.obj->data.dictionary.capacity = table_props.string_keys_num;
|
||||||
cur.container = true;
|
cur.container = true;
|
||||||
kv_push(stack, cur);
|
kvi_push(stack, cur);
|
||||||
lua_pushnil(lstate);
|
lua_pushnil(lstate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1239,7 +1241,7 @@ type_error:
|
|||||||
lua_pop(lstate, 1);
|
lua_pop(lstate, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_destroy(stack);
|
kvi_destroy(stack);
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
api_free_object(ret);
|
api_free_object(ret);
|
||||||
ret = NIL;
|
ret = NIL;
|
||||||
|
@ -86,8 +86,9 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
|
|||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE;
|
kvec_withinit_t(MPToAPIObjectStackItem, 2) stack = KV_INITIAL_VALUE;
|
||||||
kv_push(stack, ((MPToAPIObjectStackItem) {
|
kvi_init(stack);
|
||||||
|
kvi_push(stack, ((MPToAPIObjectStackItem) {
|
||||||
.mobj = obj,
|
.mobj = obj,
|
||||||
.aobj = arg,
|
.aobj = arg,
|
||||||
.container = false,
|
.container = false,
|
||||||
@ -155,7 +156,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
|
|||||||
const size_t idx = cur.idx;
|
const size_t idx = cur.idx;
|
||||||
cur.idx++;
|
cur.idx++;
|
||||||
kv_last(stack) = cur;
|
kv_last(stack) = cur;
|
||||||
kv_push(stack, ((MPToAPIObjectStackItem) {
|
kvi_push(stack, ((MPToAPIObjectStackItem) {
|
||||||
.mobj = &cur.mobj->via.array.ptr[idx],
|
.mobj = &cur.mobj->via.array.ptr[idx],
|
||||||
.aobj = &cur.aobj->data.array.items[idx],
|
.aobj = &cur.aobj->data.array.items[idx],
|
||||||
.container = false,
|
.container = false,
|
||||||
@ -209,7 +210,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kv_push(stack, ((MPToAPIObjectStackItem) {
|
kvi_push(stack, ((MPToAPIObjectStackItem) {
|
||||||
.mobj = &cur.mobj->via.map.ptr[idx].val,
|
.mobj = &cur.mobj->via.map.ptr[idx].val,
|
||||||
.aobj = &cur.aobj->data.dictionary.items[idx].value,
|
.aobj = &cur.aobj->data.dictionary.items[idx].value,
|
||||||
.container = false,
|
.container = false,
|
||||||
@ -265,7 +266,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
|
|||||||
(void)kv_pop(stack);
|
(void)kv_pop(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_destroy(stack);
|
kvi_destroy(stack);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,8 +376,9 @@ typedef struct {
|
|||||||
void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
|
void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
|
||||||
FUNC_ATTR_NONNULL_ARG(2)
|
FUNC_ATTR_NONNULL_ARG(2)
|
||||||
{
|
{
|
||||||
kvec_t(APIToMPObjectStackItem) stack = KV_INITIAL_VALUE;
|
kvec_withinit_t(APIToMPObjectStackItem, 2) stack = KV_INITIAL_VALUE;
|
||||||
kv_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
|
kvi_init(stack);
|
||||||
|
kvi_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
|
||||||
while (kv_size(stack)) {
|
while (kv_size(stack)) {
|
||||||
APIToMPObjectStackItem cur = kv_last(stack);
|
APIToMPObjectStackItem cur = kv_last(stack);
|
||||||
STATIC_ASSERT(kObjectTypeWindow == kObjectTypeBuffer + 1
|
STATIC_ASSERT(kObjectTypeWindow == kObjectTypeBuffer + 1
|
||||||
@ -428,7 +430,7 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
|
|||||||
const size_t idx = cur.idx;
|
const size_t idx = cur.idx;
|
||||||
cur.idx++;
|
cur.idx++;
|
||||||
kv_last(stack) = cur;
|
kv_last(stack) = cur;
|
||||||
kv_push(stack, ((APIToMPObjectStackItem) {
|
kvi_push(stack, ((APIToMPObjectStackItem) {
|
||||||
.aobj = &cur.aobj->data.array.items[idx],
|
.aobj = &cur.aobj->data.array.items[idx],
|
||||||
.container = false,
|
.container = false,
|
||||||
}));
|
}));
|
||||||
@ -451,7 +453,7 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
|
|||||||
kv_last(stack) = cur;
|
kv_last(stack) = cur;
|
||||||
msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
|
msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
|
||||||
res);
|
res);
|
||||||
kv_push(stack, ((APIToMPObjectStackItem) {
|
kvi_push(stack, ((APIToMPObjectStackItem) {
|
||||||
.aobj = &cur.aobj->data.dictionary.items[idx].value,
|
.aobj = &cur.aobj->data.dictionary.items[idx].value,
|
||||||
.container = false,
|
.container = false,
|
||||||
}));
|
}));
|
||||||
@ -468,7 +470,7 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
|
|||||||
(void)kv_pop(stack);
|
(void)kv_pop(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kv_destroy(stack);
|
kvi_destroy(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msgpack_rpc_from_array(Array result, msgpack_packer *res)
|
void msgpack_rpc_from_array(Array result, msgpack_packer *res)
|
||||||
|
Loading…
Reference in New Issue
Block a user