comparison src/userfunc.c @ 21006:ae185f35e256 v8.2.1054

patch 8.2.1054: not so easy to pass a lua function to Vim Commit: https://github.com/vim/vim/commit/801ab069341c8652680d63c174530fd4feb2911e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jun 25 19:27:56 2020 +0200 patch 8.2.1054: not so easy to pass a lua function to Vim Problem: Not so easy to pass a lua function to Vim. Solution: Convert a Lua function and closure to a Vim funcref. (Prabir Shrestha, closes #6246)
author Bram Moolenaar <Bram@vim.org>
date Thu, 25 Jun 2020 19:30:21 +0200
parents 3af71cbcfdbe
children f80e822a310d
comparison
equal deleted inserted replaced
21005:3f0abea9bed2 21006:ae185f35e256
339 339
340 sprintf((char*)name, "<lambda>%d", ++lambda_no); 340 sprintf((char*)name, "<lambda>%d", ++lambda_no);
341 return name; 341 return name;
342 } 342 }
343 343
344 #if defined(FEAT_LUA) || defined(PROTO)
345 /*
346 * Registers a native C callback which can be called from Vim script.
347 * Returns the name of the Vim script function.
348 */
349 char_u *
350 register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state)
351 {
352 char_u *name = get_lambda_name();
353 ufunc_T *fp = NULL;
354 garray_T newargs;
355 garray_T newlines;
356
357 ga_init(&newargs);
358 ga_init(&newlines);
359
360 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
361 if (fp == NULL)
362 goto errret;
363
364 fp->uf_dfunc_idx = UF_NOT_COMPILED;
365 fp->uf_refcount = 1;
366 fp->uf_varargs = TRUE;
367 fp->uf_flags = FC_CFUNC;
368 fp->uf_calls = 0;
369 fp->uf_script_ctx = current_sctx;
370 fp->uf_lines = newlines;
371 fp->uf_args = newargs;
372 fp->uf_cb = cb;
373 fp->uf_cb_free = cb_free;
374 fp->uf_cb_state = state;
375
376 set_ufunc_name(fp, name);
377 hash_add(&func_hashtab, UF2HIKEY(fp));
378
379 return name;
380
381 errret:
382 ga_clear_strings(&newargs);
383 ga_clear_strings(&newlines);
384 vim_free(fp);
385 return NULL;
386 }
387 #endif
388
344 /* 389 /*
345 * Parse a lambda expression and get a Funcref from "*arg". 390 * Parse a lambda expression and get a Funcref from "*arg".
346 * Return OK or FAIL. Returns NOTDONE for dict or {expr}. 391 * Return OK or FAIL. Returns NOTDONE for dict or {expr}.
347 */ 392 */
348 int 393 int
1025 VIM_CLEAR(fp->uf_va_name); 1070 VIM_CLEAR(fp->uf_va_name);
1026 while (fp->uf_type_list.ga_len > 0) 1071 while (fp->uf_type_list.ga_len > 0)
1027 vim_free(((type_T **)fp->uf_type_list.ga_data) 1072 vim_free(((type_T **)fp->uf_type_list.ga_data)
1028 [--fp->uf_type_list.ga_len]); 1073 [--fp->uf_type_list.ga_len]);
1029 ga_clear(&fp->uf_type_list); 1074 ga_clear(&fp->uf_type_list);
1075
1076 #ifdef FEAT_LUA
1077 if (fp->uf_cb_free != NULL)
1078 {
1079 fp->uf_cb_free(fp->uf_cb_state);
1080 fp->uf_cb_free = NULL;
1081 }
1082
1083 fp->uf_cb_state = NULL;
1084 fp->uf_cb = NULL;
1085 #endif
1030 #ifdef FEAT_PROFILE 1086 #ifdef FEAT_PROFILE
1031 VIM_CLEAR(fp->uf_tml_count); 1087 VIM_CLEAR(fp->uf_tml_count);
1032 VIM_CLEAR(fp->uf_tml_total); 1088 VIM_CLEAR(fp->uf_tml_total);
1033 VIM_CLEAR(fp->uf_tml_self); 1089 VIM_CLEAR(fp->uf_tml_self);
1034 #endif 1090 #endif
1971 fp = find_func(p, FALSE, NULL); 2027 fp = find_func(p, FALSE, NULL);
1972 } 2028 }
1973 2029
1974 if (fp != NULL && (fp->uf_flags & FC_DELETED)) 2030 if (fp != NULL && (fp->uf_flags & FC_DELETED))
1975 error = FCERR_DELETED; 2031 error = FCERR_DELETED;
2032 #ifdef FEAT_LUA
2033 else if (fp != NULL && (fp->uf_flags & FC_CFUNC))
2034 {
2035 cfunc_T cb = fp->uf_cb;
2036
2037 error = (*cb)(argcount, argvars, rettv, fp->uf_cb_state);
2038 }
2039 #endif
1976 else if (fp != NULL) 2040 else if (fp != NULL)
1977 { 2041 {
1978 if (funcexe->argv_func != NULL) 2042 if (funcexe->argv_func != NULL)
1979 // postponed filling in the arguments, do it now 2043 // postponed filling in the arguments, do it now
1980 argcount = funcexe->argv_func(argcount, argvars, argv_clear, 2044 argcount = funcexe->argv_func(argcount, argvars, argv_clear,