diff options
author | Famiu Haque <famiuhaque@protonmail.com> | 2022-09-14 11:01:39 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-14 13:01:39 +0800 |
commit | bd4eca11464dc65d40a58444aa67bd0f3553ae0c (patch) | |
tree | c05b4e25716819ffdf3b0f6a13119e8e33f03bfa /src | |
parent | 1e5daed67693f88d3ad515cf9e2d2f6d29c48a08 (diff) | |
download | rneovim-bd4eca11464dc65d40a58444aa67bd0f3553ae0c.tar.gz rneovim-bd4eca11464dc65d40a58444aa67bd0f3553ae0c.tar.bz2 rneovim-bd4eca11464dc65d40a58444aa67bd0f3553ae0c.zip |
refactor: move definitions from `typval.h` to `typval_defs.h` (#20194)
Taken from #20187.
Diffstat (limited to 'src')
-rwxr-xr-x | src/clint.py | 2 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 399 | ||||
-rw-r--r-- | src/nvim/eval/typval_defs.h | 399 |
3 files changed, 402 insertions, 398 deletions
diff --git a/src/clint.py b/src/clint.py index 0556f53372..c4ddbf706e 100755 --- a/src/clint.py +++ b/src/clint.py @@ -2700,7 +2700,7 @@ def CheckLanguage(filename, clean_lines, linenum, error): if match: error(filename, linenum, 'runtime/printf', 4, 'Use xstrlcat or snprintf instead of %s' % match.group(1)) - if not Search(r'eval/typval\.[ch]$', filename): + if not Search(r'eval/typval\.[ch]$|eval/typval_defs\.h$', filename): match = Search(r'(?:\.|->)' r'(?:lv_(?:first|last|refcount|len|watch|idx(?:_item)?' r'|copylist|lock)' diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 6373ead1a3..0a4adc1f53 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -2,405 +2,19 @@ #define NVIM_EVAL_TYPVAL_H #include <assert.h> -#include <inttypes.h> #include <stdbool.h> #include <stddef.h> #include <string.h> +#include "nvim/eval/typval_defs.h" #include "nvim/func_attr.h" -#include "nvim/garray.h" #include "nvim/gettext.h" -#include "nvim/hashtab.h" -#include "nvim/lib/queue.h" #include "nvim/macros.h" #include "nvim/mbyte_defs.h" #include "nvim/message.h" -#include "nvim/pos.h" // for linenr_T -#include "nvim/types.h" -#ifdef LOG_LIST_ACTIONS -# include "nvim/memory.h" -#endif - -/// Type used for VimL VAR_NUMBER values -typedef int64_t varnumber_T; -typedef uint64_t uvarnumber_T; - -/// Refcount for dict or list that should not be freed -enum { DO_NOT_FREE_CNT = (INT_MAX / 2), }; - -/// Additional values for tv_list_alloc() len argument -enum ListLenSpecials { - /// List length is not known in advance - /// - /// To be used when there is neither a way to know how many elements will be - /// needed nor are any educated guesses. - kListLenUnknown = -1, - /// List length *should* be known, but is actually not - /// - /// All occurrences of this value should be eventually removed. This is for - /// the case when the only reason why list length is not known is that it - /// would be hard to code without refactoring, but refactoring is needed. - kListLenShouldKnow = -2, - /// List length may be known in advance, but it requires too much effort - /// - /// To be used when it looks impractical to determine list length. - kListLenMayKnow = -3, -}; - -/// Maximal possible value of varnumber_T variable -#define VARNUMBER_MAX INT64_MAX -#define UVARNUMBER_MAX UINT64_MAX - -/// Minimal possible value of varnumber_T variable -#define VARNUMBER_MIN INT64_MIN - -/// %d printf format specifier for varnumber_T -#define PRIdVARNUMBER PRId64 - -typedef struct listvar_S list_T; -typedef struct dictvar_S dict_T; -typedef struct partial_S partial_T; -typedef struct blobvar_S blob_T; - -typedef struct ufunc ufunc_T; - -typedef enum { - kCallbackNone = 0, - kCallbackFuncref, - kCallbackPartial, - kCallbackLua, -} CallbackType; - -typedef struct { - union { - char *funcref; - partial_T *partial; - LuaRef luaref; - } data; - CallbackType type; -} Callback; - -#define CALLBACK_INIT { .type = kCallbackNone } -#define CALLBACK_NONE ((Callback)CALLBACK_INIT) - -/// Structure holding dictionary watcher -typedef struct dict_watcher { - Callback callback; - char *key_pattern; - size_t key_pattern_len; - QUEUE node; - bool busy; // prevent recursion if the dict is changed in the callback - bool needs_free; -} DictWatcher; - -/// Bool variable values -typedef enum { - kBoolVarFalse, ///< v:false - kBoolVarTrue, ///< v:true -} BoolVarValue; - -/// Special variable values -typedef enum { - kSpecialVarNull, ///< v:null -} SpecialVarValue; - -/// Variable lock status for typval_T.v_lock -typedef enum { - VAR_UNLOCKED = 0, ///< Not locked. - VAR_LOCKED = 1, ///< User lock, can be unlocked. - VAR_FIXED = 2, ///< Locked forever. -} VarLockStatus; - -/// VimL variable types, for use in typval_T.v_type -typedef enum { - VAR_UNKNOWN = 0, ///< Unknown (unspecified) value. - VAR_NUMBER, ///< Number, .v_number is used. - VAR_STRING, ///< String, .v_string is used. - VAR_FUNC, ///< Function reference, .v_string is used as function name. - VAR_LIST, ///< List, .v_list is used. - VAR_DICT, ///< Dictionary, .v_dict is used. - VAR_FLOAT, ///< Floating-point value, .v_float is used. - VAR_BOOL, ///< true, false - VAR_SPECIAL, ///< Special value (null), .v_special - ///< is used. - VAR_PARTIAL, ///< Partial, .v_partial is used. - VAR_BLOB, ///< Blob, .v_blob is used. -} VarType; - -/// Structure that holds an internal variable value -typedef struct { - VarType v_type; ///< Variable type. - VarLockStatus v_lock; ///< Variable lock status. - union typval_vval_union { - varnumber_T v_number; ///< Number, for VAR_NUMBER. - BoolVarValue v_bool; ///< Bool value, for VAR_BOOL - SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL. - float_T v_float; ///< Floating-point number, for VAR_FLOAT. - char *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL. - list_T *v_list; ///< List for VAR_LIST, can be NULL. - dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL. - partial_T *v_partial; ///< Closure: function with args. - blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL. - } vval; ///< Actual value. -} typval_T; - -/// Values for (struct dictvar_S).dv_scope -typedef enum { - VAR_NO_SCOPE = 0, ///< Not a scope dictionary. - VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …). - VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix - ///< (l:, g:). -} ScopeType; - -/// Structure to hold an item of a list -typedef struct listitem_S listitem_T; - -struct listitem_S { - listitem_T *li_next; ///< Next item in list. - listitem_T *li_prev; ///< Previous item in list. - typval_T li_tv; ///< Item value. -}; - -/// Structure used by those that are using an item in a list -typedef struct listwatch_S listwatch_T; - -struct listwatch_S { - listitem_T *lw_item; ///< Item being watched. - listwatch_T *lw_next; ///< Next watcher. -}; - -/// Structure to hold info about a list -/// Order of members is optimized to reduce padding. -struct listvar_S { - listitem_T *lv_first; ///< First item, NULL if none. - listitem_T *lv_last; ///< Last item, NULL if none. - listwatch_T *lv_watch; ///< First watcher, NULL if none. - listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx". - list_T *lv_copylist; ///< Copied list used by deepcopy(). - list_T *lv_used_next; ///< next list in used lists list. - list_T *lv_used_prev; ///< Previous list in used lists list. - int lv_refcount; ///< Reference count. - int lv_len; ///< Number of items. - int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx]. - int lv_copyID; ///< ID used by deepcopy(). - VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED. - - LuaRef lua_table_ref; -}; - -// Static list with 10 items. Use tv_list_init_static10() to initialize. -typedef struct { - list_T sl_list; // must be first - listitem_T sl_items[10]; -} staticList10_T; - -#define TV_LIST_STATIC10_INIT { \ - .sl_list = { \ - .lv_first = NULL, \ - .lv_last = NULL, \ - .lv_refcount = 0, \ - .lv_len = 0, \ - .lv_watch = NULL, \ - .lv_idx_item = NULL, \ - .lv_lock = VAR_FIXED, \ - .lv_used_next = NULL, \ - .lv_used_prev = NULL, \ - }, \ -} - -#define TV_DICTITEM_STRUCT(...) \ - struct { \ - typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ - uint8_t di_flags; /* Flags. */ \ - char_u di_key[__VA_ARGS__]; /* Key value. */ \ - } - -/// Structure to hold a scope dictionary -/// -/// @warning Must be compatible with dictitem_T. -/// -/// For use in find_var_in_ht to pretend that it found dictionary item when it -/// finds scope dictionary. -typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem; - -/// Structure to hold an item of a Dictionary -/// -/// @warning Must be compatible with ScopeDictDictItem. -/// -/// Also used for a variable. -typedef TV_DICTITEM_STRUCT() dictitem_T; - -/// Flags for dictitem_T.di_flags -typedef enum { - DI_FLAGS_RO = 1, ///< Read-only value - DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox - DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d. - DI_FLAGS_LOCK = 8, ///< Locked value. - DI_FLAGS_ALLOC = 16, ///< Separately allocated. -} DictItemFlags; - -/// Structure representing a Dictionary -struct dictvar_S { - VarLockStatus dv_lock; ///< Whole dictionary lock status. - ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if - ///< dictionary represents a scope (i.e. g:, l: …). - int dv_refcount; ///< Reference count. - int dv_copyID; ///< ID used when recursivery traversing a value. - hashtab_T dv_hashtab; ///< Hashtab containing all items. - dict_T *dv_copydict; ///< Copied dict used by deepcopy(). - dict_T *dv_used_next; ///< Next dictionary in used dictionaries list. - dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list. - QUEUE watchers; ///< Dictionary key watchers set by user code. - - LuaRef lua_table_ref; -}; - -/// Structure to hold info about a Blob -struct blobvar_S { - garray_T bv_ga; ///< Growarray with the data. - int bv_refcount; ///< Reference count. - VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED. -}; - -/// Type used for script ID -typedef int scid_T; -/// Format argument for scid_T -#define PRIdSCID "d" - -// SCript ConteXt (SCTX): identifies a script line. -// When sourcing a script "sc_lnum" is zero, "sourcing_lnum" is the current -// line number. When executing a user function "sc_lnum" is the line where the -// function was defined, "sourcing_lnum" is the line number inside the -// function. When stored with a function, mapping, option, etc. "sc_lnum" is -// the line number in the script "sc_sid". -typedef struct { - scid_T sc_sid; // script ID - int sc_seq; // sourcing sequence number - linenr_T sc_lnum; // line number -} sctx_T; - -/// Maximum number of function arguments -#define MAX_FUNC_ARGS 20 -/// Short variable name length -#define VAR_SHORT_LEN 20 -/// Number of fixed variables used for arguments -#define FIXVAR_CNT 12 - -// Structure to hold info for a function that is currently being executed. -typedef struct funccall_S funccall_T; - -struct funccall_S { - ufunc_T *func; ///< Function being called. - int linenr; ///< Next line to be executed. - int returned; ///< ":return" used. - /// Fixed variables for arguments. - TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT]; - dict_T l_vars; ///< l: local function variables. - ScopeDictDictItem l_vars_var; ///< Variable for l: scope. - dict_T l_avars; ///< a: argument variables. - ScopeDictDictItem l_avars_var; ///< Variable for a: scope. - list_T l_varlist; ///< List for a:000. - listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000. - typval_T *rettv; ///< Return value. - linenr_T breakpoint; ///< Next line with breakpoint or zero. - int dbg_tick; ///< Debug_tick when breakpoint was set. - int level; ///< Top nesting level of executed function. - proftime_T prof_child; ///< Time spent in a child. - funccall_T *caller; ///< Calling function or NULL; or next funccal in - ///< list pointed to by previous_funccal. - int fc_refcount; ///< Number of user functions that reference this funccall. - int fc_copyID; ///< CopyID used for garbage collection. - garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func". -}; - -/// Structure to hold info for a user function. -struct ufunc { - int uf_varargs; ///< variable nr of arguments - int uf_flags; - int uf_calls; ///< nr of active calls - bool uf_cleared; ///< func_clear() was already called - garray_T uf_args; ///< arguments - garray_T uf_def_args; ///< default argument expressions - garray_T uf_lines; ///< function lines - int uf_profiling; ///< true when func is being profiled - int uf_prof_initialized; - LuaRef uf_luaref; ///< lua callback, used if (uf_flags & FC_LUAREF) - // Profiling the function as a whole. - int uf_tm_count; ///< nr of calls - proftime_T uf_tm_total; ///< time spent in function + children - proftime_T uf_tm_self; ///< time spent in function itself - proftime_T uf_tm_children; ///< time spent in children this call - // Profiling the function per line. - int *uf_tml_count; ///< nr of times line was executed - proftime_T *uf_tml_total; ///< time spent in a line + children - proftime_T *uf_tml_self; ///< time spent in a line itself - proftime_T uf_tml_start; ///< start time for current line - proftime_T uf_tml_children; ///< time spent in children for this line - proftime_T uf_tml_wait; ///< start wait time for current line - int uf_tml_idx; ///< index of line being timed; -1 if none - int uf_tml_execed; ///< line being timed was executed - sctx_T uf_script_ctx; ///< SCTX where function was defined, - ///< used for s: variables - int uf_refcount; ///< reference count, see func_name_refcount() - funccall_T *uf_scoped; ///< l: local variables for closure - char_u *uf_name_exp; ///< if "uf_name[]" starts with SNR the name with - ///< "<SNR>" as a string, otherwise NULL - char_u uf_name[]; ///< Name of function (actual size equals name); - ///< can start with <SNR>123_ - ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) -}; - -struct partial_S { - int pt_refcount; ///< Reference count. - char *pt_name; ///< Function name; when NULL use pt_func->name. - ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with pt_name. - bool pt_auto; ///< When true the partial was created by using dict.member - ///< in handle_subscript(). - int pt_argc; ///< Number of arguments. - typval_T *pt_argv; ///< Arguments in allocated array. - dict_T *pt_dict; ///< Dict for "self". -}; - -/// Structure used for explicit stack while garbage collecting hash tables -typedef struct ht_stack_S { - hashtab_T *ht; - struct ht_stack_S *prev; -} ht_stack_T; - -/// Structure used for explicit stack while garbage collecting lists -typedef struct list_stack_S { - list_T *list; - struct list_stack_S *prev; -} list_stack_T; - -/// Structure representing one list item, used for sort array. -typedef struct { - listitem_T *item; ///< Sorted list item. - int idx; ///< Sorted list item index. -} ListSortItem; - -typedef int (*ListSorter)(const void *, const void *); #ifdef LOG_LIST_ACTIONS - -/// List actions log entry -typedef struct { - uintptr_t l; ///< List log entry belongs to. - uintptr_t li1; ///< First list item log entry belongs to, if applicable. - uintptr_t li2; ///< Second list item log entry belongs to, if applicable. - int len; ///< List length when log entry was created. - const char *action; ///< Logged action. -} ListLogEntry; - -typedef struct list_log ListLog; - -/// List actions log -struct list_log { - ListLog *next; ///< Next chunk or NULL. - size_t capacity; ///< Number of entries in current chunk. - size_t size; ///< Current chunk size. - ListLogEntry entries[]; ///< Actual log entries. -}; +# include "nvim/memory.h" extern ListLog *list_log_first; ///< First list log chunk, NULL if missing extern ListLog *list_log_last; ///< Last list log chunk @@ -780,12 +394,6 @@ static inline void tv_init(typval_T *const tv) } } -#define TV_INITIAL_VALUE \ - ((typval_T) { \ - .v_type = VAR_UNKNOWN, \ - .v_lock = VAR_UNLOCKED, \ - }) - /// Empty string /// /// Needed for hack which allows not allocating empty string and still not @@ -884,9 +492,6 @@ static inline bool tv_get_float_chk(const typval_T *const tv, float_T *const ret_f) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT; -// FIXME circular dependency, cannot import message.h. -bool semsg(const char *const fmt, ...); - /// Get the float value /// /// Raises an error if object is not number or floating-point. diff --git a/src/nvim/eval/typval_defs.h b/src/nvim/eval/typval_defs.h new file mode 100644 index 0000000000..1c0a438751 --- /dev/null +++ b/src/nvim/eval/typval_defs.h @@ -0,0 +1,399 @@ +#ifndef NVIM_EVAL_TYPVAL_DEFS_H +#define NVIM_EVAL_TYPVAL_DEFS_H + +#include <inttypes.h> +#include <limits.h> + +#include "nvim/garray.h" +#include "nvim/hashtab.h" +#include "nvim/lib/queue.h" +#include "nvim/pos.h" +#include "nvim/types.h" + +/// Type used for VimL VAR_NUMBER values +typedef int64_t varnumber_T; +typedef uint64_t uvarnumber_T; + +/// Refcount for dict or list that should not be freed +enum { DO_NOT_FREE_CNT = (INT_MAX / 2), }; + +/// Additional values for tv_list_alloc() len argument +enum ListLenSpecials { + /// List length is not known in advance + /// + /// To be used when there is neither a way to know how many elements will be + /// needed nor are any educated guesses. + kListLenUnknown = -1, + /// List length *should* be known, but is actually not + /// + /// All occurrences of this value should be eventually removed. This is for + /// the case when the only reason why list length is not known is that it + /// would be hard to code without refactoring, but refactoring is needed. + kListLenShouldKnow = -2, + /// List length may be known in advance, but it requires too much effort + /// + /// To be used when it looks impractical to determine list length. + kListLenMayKnow = -3, +}; + +/// Maximal possible value of varnumber_T variable +#define VARNUMBER_MAX INT64_MAX +#define UVARNUMBER_MAX UINT64_MAX + +/// Minimal possible value of varnumber_T variable +#define VARNUMBER_MIN INT64_MIN + +/// %d printf format specifier for varnumber_T +#define PRIdVARNUMBER PRId64 + +typedef struct listvar_S list_T; +typedef struct dictvar_S dict_T; +typedef struct partial_S partial_T; +typedef struct blobvar_S blob_T; + +typedef struct ufunc ufunc_T; + +typedef enum { + kCallbackNone = 0, + kCallbackFuncref, + kCallbackPartial, + kCallbackLua, +} CallbackType; + +typedef struct { + union { + char *funcref; + partial_T *partial; + LuaRef luaref; + } data; + CallbackType type; +} Callback; + +#define CALLBACK_INIT { .type = kCallbackNone } +#define CALLBACK_NONE ((Callback)CALLBACK_INIT) + +/// Structure holding dictionary watcher +typedef struct dict_watcher { + Callback callback; + char *key_pattern; + size_t key_pattern_len; + QUEUE node; + bool busy; // prevent recursion if the dict is changed in the callback + bool needs_free; +} DictWatcher; + +/// Bool variable values +typedef enum { + kBoolVarFalse, ///< v:false + kBoolVarTrue, ///< v:true +} BoolVarValue; + +/// Special variable values +typedef enum { + kSpecialVarNull, ///< v:null +} SpecialVarValue; + +/// Variable lock status for typval_T.v_lock +typedef enum { + VAR_UNLOCKED = 0, ///< Not locked. + VAR_LOCKED = 1, ///< User lock, can be unlocked. + VAR_FIXED = 2, ///< Locked forever. +} VarLockStatus; + +/// VimL variable types, for use in typval_T.v_type +typedef enum { + VAR_UNKNOWN = 0, ///< Unknown (unspecified) value. + VAR_NUMBER, ///< Number, .v_number is used. + VAR_STRING, ///< String, .v_string is used. + VAR_FUNC, ///< Function reference, .v_string is used as function name. + VAR_LIST, ///< List, .v_list is used. + VAR_DICT, ///< Dictionary, .v_dict is used. + VAR_FLOAT, ///< Floating-point value, .v_float is used. + VAR_BOOL, ///< true, false + VAR_SPECIAL, ///< Special value (null), .v_special is used. + VAR_PARTIAL, ///< Partial, .v_partial is used. + VAR_BLOB, ///< Blob, .v_blob is used. +} VarType; + +/// Structure that holds an internal variable value +typedef struct { + VarType v_type; ///< Variable type. + VarLockStatus v_lock; ///< Variable lock status. + union typval_vval_union { + varnumber_T v_number; ///< Number, for VAR_NUMBER. + BoolVarValue v_bool; ///< Bool value, for VAR_BOOL + SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL. + float_T v_float; ///< Floating-point number, for VAR_FLOAT. + char *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL. + list_T *v_list; ///< List for VAR_LIST, can be NULL. + dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL. + partial_T *v_partial; ///< Closure: function with args. + blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL. + } vval; ///< Actual value. +} typval_T; + +#define TV_INITIAL_VALUE \ + ((typval_T) { \ + .v_type = VAR_UNKNOWN, \ + .v_lock = VAR_UNLOCKED, \ + }) + +/// Values for (struct dictvar_S).dv_scope +typedef enum { + VAR_NO_SCOPE = 0, ///< Not a scope dictionary. + VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …). + VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix + ///< (l:, g:). +} ScopeType; + +/// Structure to hold an item of a list +typedef struct listitem_S listitem_T; + +struct listitem_S { + listitem_T *li_next; ///< Next item in list. + listitem_T *li_prev; ///< Previous item in list. + typval_T li_tv; ///< Item value. +}; + +/// Structure used by those that are using an item in a list +typedef struct listwatch_S listwatch_T; + +struct listwatch_S { + listitem_T *lw_item; ///< Item being watched. + listwatch_T *lw_next; ///< Next watcher. +}; + +/// Structure to hold info about a list +/// Order of members is optimized to reduce padding. +struct listvar_S { + listitem_T *lv_first; ///< First item, NULL if none. + listitem_T *lv_last; ///< Last item, NULL if none. + listwatch_T *lv_watch; ///< First watcher, NULL if none. + listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx". + list_T *lv_copylist; ///< Copied list used by deepcopy(). + list_T *lv_used_next; ///< next list in used lists list. + list_T *lv_used_prev; ///< Previous list in used lists list. + int lv_refcount; ///< Reference count. + int lv_len; ///< Number of items. + int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx]. + int lv_copyID; ///< ID used by deepcopy(). + VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED. + + LuaRef lua_table_ref; +}; + +/// Static list with 10 items. Use tv_list_init_static10() to initialize. +typedef struct { + list_T sl_list; // must be first + listitem_T sl_items[10]; +} staticList10_T; + +#define TV_LIST_STATIC10_INIT { \ + .sl_list = { \ + .lv_first = NULL, \ + .lv_last = NULL, \ + .lv_refcount = 0, \ + .lv_len = 0, \ + .lv_watch = NULL, \ + .lv_idx_item = NULL, \ + .lv_lock = VAR_FIXED, \ + .lv_used_next = NULL, \ + .lv_used_prev = NULL, \ + }, \ +} + +#define TV_DICTITEM_STRUCT(...) \ + struct { \ + typval_T di_tv; /* Structure that holds scope dictionary itself. */ \ + uint8_t di_flags; /* Flags. */ \ + char_u di_key[__VA_ARGS__]; /* Key value. */ \ + } + +/// Structure to hold a scope dictionary +/// +/// @warning Must be compatible with dictitem_T. +/// +/// For use in find_var_in_ht to pretend that it found dictionary item when it +/// finds scope dictionary. +typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem; + +/// Structure to hold an item of a Dictionary +/// +/// @warning Must be compatible with ScopeDictDictItem. +/// +/// Also used for a variable. +typedef TV_DICTITEM_STRUCT() dictitem_T; + +/// Flags for dictitem_T.di_flags +typedef enum { + DI_FLAGS_RO = 1, ///< Read-only value + DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox + DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d. + DI_FLAGS_LOCK = 8, ///< Locked value. + DI_FLAGS_ALLOC = 16, ///< Separately allocated. +} DictItemFlags; + +/// Structure representing a Dictionary +struct dictvar_S { + VarLockStatus dv_lock; ///< Whole dictionary lock status. + ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if + ///< dictionary represents a scope (i.e. g:, l: …). + int dv_refcount; ///< Reference count. + int dv_copyID; ///< ID used when recursivery traversing a value. + hashtab_T dv_hashtab; ///< Hashtab containing all items. + dict_T *dv_copydict; ///< Copied dict used by deepcopy(). + dict_T *dv_used_next; ///< Next dictionary in used dictionaries list. + dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list. + QUEUE watchers; ///< Dictionary key watchers set by user code. + + LuaRef lua_table_ref; +}; + +/// Structure to hold info about a Blob +struct blobvar_S { + garray_T bv_ga; ///< Growarray with the data. + int bv_refcount; ///< Reference count. + VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED. +}; + +/// Type used for script ID +typedef int scid_T; +/// Format argument for scid_T +#define PRIdSCID "d" + +/// SCript ConteXt (SCTX): identifies a script line. +/// When sourcing a script "sc_lnum" is zero, "sourcing_lnum" is the current +/// line number. When executing a user function "sc_lnum" is the line where the +/// function was defined, "sourcing_lnum" is the line number inside the +/// function. When stored with a function, mapping, option, etc. "sc_lnum" is +/// the line number in the script "sc_sid". +typedef struct { + scid_T sc_sid; ///< script ID + int sc_seq; ///< sourcing sequence number + linenr_T sc_lnum; ///< line number +} sctx_T; + +/// Maximum number of function arguments +enum { MAX_FUNC_ARGS = 20, }; +/// Short variable name length +enum { VAR_SHORT_LEN = 20, }; +/// Number of fixed variables used for arguments +enum { FIXVAR_CNT = 12, }; + +/// Structure to hold info for a function that is currently being executed. +typedef struct funccall_S funccall_T; + +struct funccall_S { + ufunc_T *func; ///< Function being called. + int linenr; ///< Next line to be executed. + int returned; ///< ":return" used. + /// Fixed variables for arguments. + TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT]; + dict_T l_vars; ///< l: local function variables. + ScopeDictDictItem l_vars_var; ///< Variable for l: scope. + dict_T l_avars; ///< a: argument variables. + ScopeDictDictItem l_avars_var; ///< Variable for a: scope. + list_T l_varlist; ///< List for a:000. + listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000. + typval_T *rettv; ///< Return value. + linenr_T breakpoint; ///< Next line with breakpoint or zero. + int dbg_tick; ///< debug_tick when breakpoint was set. + int level; ///< Top nesting level of executed function. + proftime_T prof_child; ///< Time spent in a child. + funccall_T *caller; ///< Calling function or NULL; or next funccal in + ///< list pointed to by previous_funccal. + int fc_refcount; ///< Number of user functions that reference this funccall. + int fc_copyID; ///< CopyID used for garbage collection. + garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func". +}; + +/// Structure to hold info for a user function. +struct ufunc { + int uf_varargs; ///< variable nr of arguments + int uf_flags; + int uf_calls; ///< nr of active calls + bool uf_cleared; ///< func_clear() was already called + garray_T uf_args; ///< arguments + garray_T uf_def_args; ///< default argument expressions + garray_T uf_lines; ///< function lines + int uf_profiling; ///< true when func is being profiled + int uf_prof_initialized; + LuaRef uf_luaref; ///< lua callback, used if (uf_flags & FC_LUAREF) + // Profiling the function as a whole. + int uf_tm_count; ///< nr of calls + proftime_T uf_tm_total; ///< time spent in function + children + proftime_T uf_tm_self; ///< time spent in function itself + proftime_T uf_tm_children; ///< time spent in children this call + // Profiling the function per line. + int *uf_tml_count; ///< nr of times line was executed + proftime_T *uf_tml_total; ///< time spent in a line + children + proftime_T *uf_tml_self; ///< time spent in a line itself + proftime_T uf_tml_start; ///< start time for current line + proftime_T uf_tml_children; ///< time spent in children for this line + proftime_T uf_tml_wait; ///< start wait time for current line + int uf_tml_idx; ///< index of line being timed; -1 if none + int uf_tml_execed; ///< line being timed was executed + sctx_T uf_script_ctx; ///< SCTX where function was defined, + ///< used for s: variables + int uf_refcount; ///< reference count, see func_name_refcount() + funccall_T *uf_scoped; ///< l: local variables for closure + char_u *uf_name_exp; ///< if "uf_name[]" starts with SNR the name with + ///< "<SNR>" as a string, otherwise NULL + char_u uf_name[]; ///< Name of function (actual size equals name); + ///< can start with <SNR>123_ + ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) +}; + +struct partial_S { + int pt_refcount; ///< Reference count. + char *pt_name; ///< Function name; when NULL use pt_func->name. + ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with pt_name. + bool pt_auto; ///< When true the partial was created by using dict.member + ///< in handle_subscript(). + int pt_argc; ///< Number of arguments. + typval_T *pt_argv; ///< Arguments in allocated array. + dict_T *pt_dict; ///< Dict for "self". +}; + +/// Structure used for explicit stack while garbage collecting hash tables +typedef struct ht_stack_S { + hashtab_T *ht; + struct ht_stack_S *prev; +} ht_stack_T; + +/// Structure used for explicit stack while garbage collecting lists +typedef struct list_stack_S { + list_T *list; + struct list_stack_S *prev; +} list_stack_T; + +/// Structure representing one list item, used for sort array. +typedef struct { + listitem_T *item; ///< Sorted list item. + int idx; ///< Sorted list item index. +} ListSortItem; + +typedef int (*ListSorter)(const void *, const void *); + +#ifdef LOG_LIST_ACTIONS +/// List actions log entry +typedef struct { + uintptr_t l; ///< List log entry belongs to. + uintptr_t li1; ///< First list item log entry belongs to, if applicable. + uintptr_t li2; ///< Second list item log entry belongs to, if applicable. + int len; ///< List length when log entry was created. + const char *action; ///< Logged action. +} ListLogEntry; + +typedef struct list_log ListLog; + +/// List actions log +struct list_log { + ListLog *next; ///< Next chunk or NULL. + size_t capacity; ///< Number of entries in current chunk. + size_t size; ///< Current chunk size. + ListLogEntry entries[]; ///< Actual log entries. +}; +#endif + +#endif // NVIM_EVAL_TYPVAL_DEFS_H |