refactor(api): use arena for metadata; msgpack_rpc_to_object delenda est

Note: kSDItemHeader is something is _written_ by nvim in the shada file
to identify it for debugging purposes outside of nvim. But this data wasn't ever used by
neovim after reading the file back, So I removed the parsing of it for now.
This commit is contained in:
bfredl
2024-02-18 12:51:27 +01:00
parent 93c911e52f
commit bbf6d4a4bc
6 changed files with 71 additions and 312 deletions

View File

@@ -30,6 +30,7 @@
#include "nvim/memory_defs.h"
#include "nvim/message.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/unpacker.h"
#include "nvim/pos_defs.h"
#include "nvim/types_defs.h"
#include "nvim/ui.h"
@@ -650,102 +651,87 @@ void api_clear_error(Error *value)
value->type = kErrorTypeNone;
}
// initialized once, never freed
static ArenaMem mem_for_metadata = NULL;
/// @returns a shared value. caller must not modify it!
Dictionary api_metadata(void)
{
static Dictionary metadata = ARRAY_DICT_INIT;
if (!metadata.size) {
PUT(metadata, "version", DICTIONARY_OBJ(version_dict()));
init_function_metadata(&metadata);
init_ui_event_metadata(&metadata);
init_error_type_metadata(&metadata);
init_type_metadata(&metadata);
Arena arena = ARENA_EMPTY;
Error err = ERROR_INIT;
metadata = arena_dict(&arena, 6);
PUT_C(metadata, "version", DICTIONARY_OBJ(version_dict(&arena)));
PUT_C(metadata, "functions",
unpack((char *)funcs_metadata, sizeof(funcs_metadata), &arena, &err));
if (ERROR_SET(&err)) {
abort();
}
PUT_C(metadata, "ui_events",
unpack((char *)ui_events_metadata, sizeof(ui_events_metadata), &arena, &err));
if (ERROR_SET(&err)) {
abort();
}
PUT_C(metadata, "ui_options", ARRAY_OBJ(ui_options_metadata(&arena)));
PUT_C(metadata, "error_types", DICTIONARY_OBJ(error_type_metadata(&arena)));
PUT_C(metadata, "types", DICTIONARY_OBJ(type_metadata(&arena)));
mem_for_metadata = arena_finish(&arena);
}
return metadata;
}
static void init_function_metadata(Dictionary *metadata)
static Array ui_options_metadata(Arena *arena)
{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
if (msgpack_unpack_next(&unpacked,
(const char *)funcs_metadata,
sizeof(funcs_metadata),
NULL) != MSGPACK_UNPACK_SUCCESS) {
abort();
}
Object functions;
msgpack_rpc_to_object(&unpacked.data, &functions);
msgpack_unpacked_destroy(&unpacked);
PUT(*metadata, "functions", functions);
}
static void init_ui_event_metadata(Dictionary *metadata)
{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
if (msgpack_unpack_next(&unpacked,
(const char *)ui_events_metadata,
sizeof(ui_events_metadata),
NULL) != MSGPACK_UNPACK_SUCCESS) {
abort();
}
Object ui_events;
msgpack_rpc_to_object(&unpacked.data, &ui_events);
msgpack_unpacked_destroy(&unpacked);
PUT(*metadata, "ui_events", ui_events);
Array ui_options = ARRAY_DICT_INIT;
ADD(ui_options, CSTR_TO_OBJ("rgb"));
Array ui_options = arena_array(arena, kUIExtCount + 1);
ADD_C(ui_options, CSTR_AS_OBJ("rgb"));
for (UIExtension i = 0; i < kUIExtCount; i++) {
if (ui_ext_names[i][0] != '_') {
ADD(ui_options, CSTR_TO_OBJ(ui_ext_names[i]));
ADD_C(ui_options, CSTR_AS_OBJ(ui_ext_names[i]));
}
}
PUT(*metadata, "ui_options", ARRAY_OBJ(ui_options));
return ui_options;
}
static void init_error_type_metadata(Dictionary *metadata)
static Dictionary error_type_metadata(Arena *arena)
{
Dictionary types = ARRAY_DICT_INIT;
Dictionary types = arena_dict(arena, 2);
Dictionary exception_metadata = ARRAY_DICT_INIT;
PUT(exception_metadata, "id", INTEGER_OBJ(kErrorTypeException));
Dictionary exception_metadata = arena_dict(arena, 1);
PUT_C(exception_metadata, "id", INTEGER_OBJ(kErrorTypeException));
Dictionary validation_metadata = ARRAY_DICT_INIT;
PUT(validation_metadata, "id", INTEGER_OBJ(kErrorTypeValidation));
Dictionary validation_metadata = arena_dict(arena, 1);
PUT_C(validation_metadata, "id", INTEGER_OBJ(kErrorTypeValidation));
PUT(types, "Exception", DICTIONARY_OBJ(exception_metadata));
PUT(types, "Validation", DICTIONARY_OBJ(validation_metadata));
PUT_C(types, "Exception", DICTIONARY_OBJ(exception_metadata));
PUT_C(types, "Validation", DICTIONARY_OBJ(validation_metadata));
PUT(*metadata, "error_types", DICTIONARY_OBJ(types));
return types;
}
static void init_type_metadata(Dictionary *metadata)
static Dictionary type_metadata(Arena *arena)
{
Dictionary types = ARRAY_DICT_INIT;
Dictionary types = arena_dict(arena, 3);
Dictionary buffer_metadata = ARRAY_DICT_INIT;
PUT(buffer_metadata, "id",
INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT));
PUT(buffer_metadata, "prefix", CSTR_TO_OBJ("nvim_buf_"));
Dictionary buffer_metadata = arena_dict(arena, 2);
PUT_C(buffer_metadata, "id", INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT));
PUT_C(buffer_metadata, "prefix", CSTR_AS_OBJ("nvim_buf_"));
Dictionary window_metadata = ARRAY_DICT_INIT;
PUT(window_metadata, "id",
INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT));
PUT(window_metadata, "prefix", CSTR_TO_OBJ("nvim_win_"));
Dictionary window_metadata = arena_dict(arena, 2);
PUT_C(window_metadata, "id", INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT));
PUT_C(window_metadata, "prefix", CSTR_AS_OBJ("nvim_win_"));
Dictionary tabpage_metadata = ARRAY_DICT_INIT;
PUT(tabpage_metadata, "id",
INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT));
PUT(tabpage_metadata, "prefix", CSTR_TO_OBJ("nvim_tabpage_"));
Dictionary tabpage_metadata = arena_dict(arena, 2);
PUT_C(tabpage_metadata, "id", INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT));
PUT_C(tabpage_metadata, "prefix", CSTR_AS_OBJ("nvim_tabpage_"));
PUT(types, "Buffer", DICTIONARY_OBJ(buffer_metadata));
PUT(types, "Window", DICTIONARY_OBJ(window_metadata));
PUT(types, "Tabpage", DICTIONARY_OBJ(tabpage_metadata));
PUT_C(types, "Buffer", DICTIONARY_OBJ(buffer_metadata));
PUT_C(types, "Window", DICTIONARY_OBJ(window_metadata));
PUT_C(types, "Tabpage", DICTIONARY_OBJ(tabpage_metadata));
PUT(*metadata, "types", DICTIONARY_OBJ(types));
return types;
}
// all the copy_[object] functions allow arena=NULL,

View File

@@ -2022,10 +2022,10 @@ void nvim__invalidate_glyph_cache(void)
must_redraw = UPD_CLEAR;
}
Object nvim__unpack(String str, Error *err)
Object nvim__unpack(String str, Arena *arena, Error *err)
FUNC_API_FAST
{
return unpack(str.data, str.size, err);
return unpack(str.data, str.size, arena, err);
}
/// Deletes an uppercase/file named mark. See |mark-motions|.