• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revision9f921ba86d05609d0cd45d2304c86dd2ef414eaf (tree)
Zeit2020-05-26 05:45:03
AutorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.0823: Vim9: script reload test is disabled

Commit: https://github.com/vim/vim/commit/25e0f5863e9010a75a1ff0d04e8f886403968755
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon May 25 22:36:50 2020 +0200

patch 8.2.0823: Vim9: script reload test is disabled
Problem: Vim9: script reload test is disabled.
Solution: Compile a function in the context of the script where it was
                1. Set execution stack for compiled function. Add a test
                  that an error is reported for the right file/function.

Ändern Zusammenfassung

Diff

diff -r cceaa5ec43aa -r 9f921ba86d05 src/ex_docmd.c
--- a/src/ex_docmd.c Mon May 25 20:45:05 2020 +0200
+++ b/src/ex_docmd.c Mon May 25 22:45:03 2020 +0200
@@ -634,8 +634,8 @@
634634 int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
635635 struct dbg_stuff debug_saved; // saved things for debug mode
636636 int initial_trylevel;
637- struct msglist **saved_msg_list = NULL;
638- struct msglist *private_msg_list;
637+ msglist_T **saved_msg_list = NULL;
638+ msglist_T *private_msg_list;
639639
640640 // "fgetline" and "cookie" passed to do_one_cmd()
641641 char_u *(*cmd_getline)(int, void *, int, int);
@@ -1238,7 +1238,7 @@
12381238 if (did_throw)
12391239 {
12401240 void *p = NULL;
1241- struct msglist *messages = NULL, *next;
1241+ msglist_T *messages = NULL, *next;
12421242
12431243 /*
12441244 * If the uncaught exception is a user exception, report it as an
diff -r cceaa5ec43aa -r 9f921ba86d05 src/ex_eval.c
--- a/src/ex_eval.c Mon May 25 20:45:05 2020 +0200
+++ b/src/ex_eval.c Mon May 25 22:45:03 2020 +0200
@@ -146,8 +146,8 @@
146146 int severe,
147147 int *ignore)
148148 {
149- struct msglist *elem;
150- struct msglist **plist;
149+ msglist_T *elem;
150+ msglist_T **plist;
151151
152152 /*
153153 * Do nothing when displaying the interrupt message or reporting an
@@ -251,7 +251,7 @@
251251 while (*plist != NULL)
252252 plist = &(*plist)->next;
253253
254- elem = ALLOC_ONE(struct msglist);
254+ elem = ALLOC_CLEAR_ONE(msglist_T);
255255 if (elem == NULL)
256256 {
257257 suppress_errthrow = TRUE;
@@ -287,6 +287,11 @@
287287 else
288288 (*msg_list)->throw_msg = tmsg;
289289 }
290+
291+ // Get the source name and lnum now, it may change before
292+ // reaching do_errthrow().
293+ elem->sfile = estack_sfile();
294+ elem->slnum = SOURCING_LNUM;
290295 }
291296 }
292297 }
@@ -298,15 +303,16 @@
298303 * Free a "msg_list" and the messages it contains.
299304 */
300305 static void
301-free_msglist(struct msglist *l)
306+free_msglist(msglist_T *l)
302307 {
303- struct msglist *messages, *next;
308+ msglist_T *messages, *next;
304309
305310 messages = l;
306311 while (messages != NULL)
307312 {
308313 next = messages->next;
309314 vim_free(messages->msg);
315+ vim_free(messages->sfile);
310316 vim_free(messages);
311317 messages = next;
312318 }
@@ -428,7 +434,7 @@
428434 if (type == ET_ERROR)
429435 {
430436 *should_free = TRUE;
431- mesg = ((struct msglist *)value)->throw_msg;
437+ mesg = ((msglist_T *)value)->throw_msg;
432438 if (cmdname != NULL && *cmdname != NUL)
433439 {
434440 cmdlen = (int)STRLEN(cmdname);
@@ -526,23 +532,34 @@
526532 if (type == ET_ERROR)
527533 // Store the original message and prefix the exception value with
528534 // "Vim:" or, if a command name is given, "Vim(cmdname):".
529- excp->messages = (struct msglist *)value;
535+ excp->messages = (msglist_T *)value;
530536
531537 excp->value = get_exception_string(value, type, cmdname, &should_free);
532538 if (excp->value == NULL && should_free)
533539 goto nomem;
534540
535541 excp->type = type;
536- excp->throw_name = estack_sfile();
537- if (excp->throw_name == NULL)
538- excp->throw_name = vim_strsave((char_u *)"");
539- if (excp->throw_name == NULL)
542+ if (type == ET_ERROR && ((msglist_T *)value)->sfile != NULL)
540543 {
541- if (should_free)
542- vim_free(excp->value);
543- goto nomem;
544+ msglist_T *entry = (msglist_T *)value;
545+
546+ excp->throw_name = entry->sfile;
547+ entry->sfile = NULL;
548+ excp->throw_lnum = entry->slnum;
544549 }
545- excp->throw_lnum = SOURCING_LNUM;
550+ else
551+ {
552+ excp->throw_name = estack_sfile();
553+ if (excp->throw_name == NULL)
554+ excp->throw_name = vim_strsave((char_u *)"");
555+ if (excp->throw_name == NULL)
556+ {
557+ if (should_free)
558+ vim_free(excp->value);
559+ goto nomem;
560+ }
561+ excp->throw_lnum = SOURCING_LNUM;
562+ }
546563
547564 if (p_verbose >= 13 || debug_break_level > 0)
548565 {
diff -r cceaa5ec43aa -r 9f921ba86d05 src/globals.h
--- a/src/globals.h Mon May 25 20:45:05 2020 +0200
+++ b/src/globals.h Mon May 25 22:45:03 2020 +0200
@@ -344,7 +344,7 @@
344344 * field of a later list element, when the "emsg_severe" flag was set when the
345345 * emsg() call was made.
346346 */
347-EXTERN struct msglist **msg_list INIT(= NULL);
347+EXTERN msglist_T **msg_list INIT(= NULL);
348348
349349 /*
350350 * suppress_errthrow: When TRUE, don't convert an error to an exception. Used
diff -r cceaa5ec43aa -r 9f921ba86d05 src/proto/scriptfile.pro
--- a/src/proto/scriptfile.pro Mon May 25 20:45:05 2020 +0200
+++ b/src/proto/scriptfile.pro Mon May 25 22:45:03 2020 +0200
@@ -1,7 +1,8 @@
11 /* scriptfile.c */
22 void estack_init(void);
33 estack_T *estack_push(etype_T type, char_u *name, long lnum);
4-void estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum);
4+void estack_push_ufunc(ufunc_T *ufunc, long lnum);
5+int estack_top_is_ufunc(ufunc_T *ufunc, long lnum);
56 void estack_pop(void);
67 char_u *estack_sfile(void);
78 void ex_runtime(exarg_T *eap);
diff -r cceaa5ec43aa -r 9f921ba86d05 src/scriptfile.c
--- a/src/scriptfile.c Mon May 25 20:45:05 2020 +0200
+++ b/src/scriptfile.c Mon May 25 22:45:03 2020 +0200
@@ -69,14 +69,31 @@
6969 * Add a user function to the execution stack.
7070 */
7171 void
72-estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum)
72+estack_push_ufunc(ufunc_T *ufunc, long lnum)
7373 {
74- estack_T *entry = estack_push(type,
74+ estack_T *entry = estack_push(ETYPE_UFUNC,
7575 ufunc->uf_name_exp != NULL
7676 ? ufunc->uf_name_exp : ufunc->uf_name, lnum);
7777 if (entry != NULL)
7878 entry->es_info.ufunc = ufunc;
7979 }
80+
81+/*
82+ * Return TRUE if "ufunc" with "lnum" is already at the top of the exe stack.
83+ */
84+ int
85+estack_top_is_ufunc(ufunc_T *ufunc, long lnum)
86+{
87+ estack_T *entry;
88+
89+ if (exestack.ga_len == 0)
90+ return FALSE;
91+ entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
92+ return entry->es_type == ETYPE_UFUNC
93+ && STRCMP( entry->es_name, ufunc->uf_name_exp != NULL
94+ ? ufunc->uf_name_exp : ufunc->uf_name) == 0
95+ && entry->es_lnum == lnum;
96+}
8097 #endif
8198
8299 /*
diff -r cceaa5ec43aa -r 9f921ba86d05 src/structs.h
--- a/src/structs.h Mon May 25 20:45:05 2020 +0200
+++ b/src/structs.h Mon May 25 22:45:03 2020 +0200
@@ -927,13 +927,16 @@
927927 * A list of error messages that can be converted to an exception. "throw_msg"
928928 * is only set in the first element of the list. Usually, it points to the
929929 * original message stored in that element, but sometimes it points to a later
930- * message in the list. See cause_errthrow() below.
930+ * message in the list. See cause_errthrow().
931931 */
932+typedef struct msglist msglist_T;
932933 struct msglist
933934 {
934- char *msg; // original message
935- char *throw_msg; // msg to throw: usually original one
936- struct msglist *next; // next of several messages in a row
935+ char *msg; // original message, allocated
936+ char *throw_msg; // msg to throw: usually original one
937+ char_u *sfile; // value from estack_sfile(), allocated
938+ long slnum; // line number for "sfile"
939+ msglist_T *next; // next of several messages in a row
937940 };
938941
939942 /*
@@ -1516,6 +1519,7 @@
15161519 #if defined(FEAT_EVAL) || defined(PROTO)
15171520 typedef struct funccall_S funccall_T;
15181521
1522+// values used for "uf_dfunc_idx"
15191523 # define UF_NOT_COMPILED -2
15201524 # define UF_TO_BE_COMPILED -1
15211525
diff -r cceaa5ec43aa -r 9f921ba86d05 src/testdir/test_vim9_script.vim
--- a/src/testdir/test_vim9_script.vim Mon May 25 20:45:05 2020 +0200
+++ b/src/testdir/test_vim9_script.vim Mon May 25 22:45:03 2020 +0200
@@ -745,9 +745,6 @@
745745 enddef
746746
747747 def Test_vim9script_reload_import()
748- " TODO: make it work to compile when not in the script context anymore
749- return
750-
751748 let lines =<< trim END
752749 vim9script
753750 const var = ''
@@ -797,9 +794,6 @@
797794 enddef
798795
799796 def Test_vim9script_reload_delfunc()
800- " TODO: make it work to compile when not in the script context anymore
801- return
802-
803797 let first_lines =<< trim END
804798 vim9script
805799 def FuncYes(): string
@@ -920,6 +914,37 @@
920914 delete('import', 'rf')
921915 enddef
922916
917+def Test_import_compile_error()
918+ let export_lines = [
919+ 'vim9script',
920+ 'export def ExpFunc(): string',
921+ ' return notDefined',
922+ 'enddef',
923+ ]
924+ writefile(export_lines, 'Xexported.vim')
925+
926+ let import_lines = [
927+ 'vim9script',
928+ 'import ExpFunc from "./Xexported.vim"',
929+ 'def ImpFunc()',
930+ ' echo ExpFunc()',
931+ 'enddef',
932+ 'defcompile',
933+ ]
934+ writefile(import_lines, 'Ximport.vim')
935+
936+ try
937+ source Ximport.vim
938+ catch /E1001/
939+ " Error should be fore the Xexported.vim file.
940+ assert_match('E1001: variable not found: notDefined', v:exception)
941+ assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
942+ endtry
943+
944+ delete('Xexported.vim')
945+ delete('Ximport.vim')
946+enddef
947+
923948 def Test_fixed_size_list()
924949 " will be allocated as one piece of memory, check that changes work
925950 let l = [1, 2, 3, 4]
diff -r cceaa5ec43aa -r 9f921ba86d05 src/userfunc.c
--- a/src/userfunc.c Mon May 25 20:45:05 2020 +0200
+++ b/src/userfunc.c Mon May 25 22:45:03 2020 +0200
@@ -1114,11 +1114,11 @@
11141114
11151115 if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
11161116 {
1117- estack_push_ufunc(ETYPE_UFUNC, fp, 1);
1117+ estack_push_ufunc(fp, 1);
11181118 save_current_sctx = current_sctx;
11191119 current_sctx = fp->uf_script_ctx;
11201120
1121- // Execute the compiled function.
1121+ // Execute the function, possibly compiling it first.
11221122 call_def_function(fp, argcount, argvars, funcexe->partial, rettv);
11231123 --depth;
11241124 current_funccal = fc->caller;
@@ -1288,7 +1288,7 @@
12881288 ++sandbox;
12891289 }
12901290
1291- estack_push_ufunc(ETYPE_UFUNC, fp, 1);
1291+ estack_push_ufunc(fp, 1);
12921292 ESTACK_CHECK_SETUP
12931293 if (p_verbose >= 12)
12941294 {
diff -r cceaa5ec43aa -r 9f921ba86d05 src/version.c
--- a/src/version.c Mon May 25 20:45:05 2020 +0200
+++ b/src/version.c Mon May 25 22:45:03 2020 +0200
@@ -747,6 +747,8 @@
747747 static int included_patches[] =
748748 { /* Add new patch number below this line */
749749 /**/
750+ 823,
751+/**/
750752 822,
751753 /**/
752754 821,
diff -r cceaa5ec43aa -r 9f921ba86d05 src/vim9compile.c
--- a/src/vim9compile.c Mon May 25 20:45:05 2020 +0200
+++ b/src/vim9compile.c Mon May 25 22:45:03 2020 +0200
@@ -2323,8 +2323,7 @@
23232323 }
23242324 line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
23252325 cctx->ctx_line_start = line;
2326- SOURCING_LNUM = cctx->ctx_ufunc->uf_script_ctx.sc_lnum
2327- + cctx->ctx_lnum + 1;
2326+ SOURCING_LNUM = cctx->ctx_lnum + 1;
23282327 } while (line == NULL || *skipwhite(line) == NUL);
23292328 return line;
23302329 }
@@ -6349,14 +6348,15 @@
63496348 int called_emsg_before = called_emsg;
63506349 int ret = FAIL;
63516350 sctx_T save_current_sctx = current_sctx;
6351+ int do_estack_push;
63526352 int emsg_before = called_emsg;
63536353
6354+ // When using a function that was compiled before: Free old instructions.
6355+ // Otherwise add a new entry in "def_functions".
63546356 if (ufunc->uf_dfunc_idx >= 0)
63556357 {
6356- // Redefining a function that was compiled before.
63576358 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
63586359 + ufunc->uf_dfunc_idx;
6359- // Free old instructions.
63606360 delete_def_function_contents(dfunc);
63616361 }
63626362 else if (add_def_function(ufunc) == FAIL)
@@ -6373,9 +6373,17 @@
63736373 ga_init2(&cctx.ctx_instr, sizeof(isn_T), 50);
63746374 instr = &cctx.ctx_instr;
63756375
6376- // Most modern script version.
6376+ // Set the context to the function, it may be compiled when called from
6377+ // another script. Set the script version to the most modern one.
6378+ // The line number will be set in next_line_from_context().
6379+ current_sctx = ufunc->uf_script_ctx;
63776380 current_sctx.sc_version = SCRIPT_VERSION_VIM9;
63786381
6382+ // Make sure error messages are OK.
6383+ do_estack_push = !estack_top_is_ufunc(ufunc, 1);
6384+ if (do_estack_push)
6385+ estack_push_ufunc(ufunc, 1);
6386+
63796387 if (ufunc->uf_def_args.ga_len > 0)
63806388 {
63816389 int count = ufunc->uf_def_args.ga_len;
@@ -6795,6 +6803,9 @@
67956803 }
67966804
67976805 current_sctx = save_current_sctx;
6806+ if (do_estack_push)
6807+ estack_pop();
6808+
67986809 free_imported(&cctx);
67996810 free_locals(&cctx);
68006811 ga_clear(&cctx.ctx_type_stack);
diff -r cceaa5ec43aa -r 9f921ba86d05 src/vim9execute.c
--- a/src/vim9execute.c Mon May 25 20:45:05 2020 +0200
+++ b/src/vim9execute.c Mon May 25 22:45:03 2020 +0200
@@ -230,7 +230,7 @@
230230 // Set execution state to the start of the called function.
231231 ectx->ec_dfunc_idx = cdf_idx;
232232 ectx->ec_instr = dfunc->df_instr;
233- estack_push_ufunc(ETYPE_UFUNC, dfunc->df_ufunc, 1);
233+ estack_push_ufunc(dfunc->df_ufunc, 1);
234234
235235 // Decide where to start execution, handles optional arguments.
236236 init_instr_idx(ufunc, argcount, ectx);
@@ -656,6 +656,7 @@
656656 int defcount = ufunc->uf_args.ga_len - argc;
657657 int save_sc_version = current_sctx.sc_version;
658658 int breakcheck_count = 0;
659+ int called_emsg_before = called_emsg;
659660
660661 // Get pointer to item in the stack.
661662 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
@@ -673,7 +674,13 @@
673674 if (ufunc->uf_dfunc_idx == UF_NOT_COMPILED
674675 || (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
675676 && compile_def_function(ufunc, FALSE, NULL) == FAIL))
677+ {
678+ if (called_emsg == called_emsg_before)
679+ semsg(_("E1091: Function is not compiled: %s"),
680+ ufunc->uf_name_exp == NULL
681+ ? ufunc->uf_name : ufunc->uf_name_exp);
676682 return FAIL;
683+ }
677684
678685 {
679686 // Check the function was really compiled.
Show on old repository browser