Mercurial > vim
comparison src/userfunc.c @ 17127:d244a9be99db v8.1.1563
patch 8.1.1563: crash when using closures
commit https://github.com/vim/vim/commit/6e5000d493b4f385f901eb97f3ce0c8088373403
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jun 17 21:18:41 2019 +0200
patch 8.1.1563: crash when using closures
Problem: Crash when using closures.
Solution: Set reference in varlist of funccal when running the garbage
collector. (Ozaki Kiichi, closes #4554, closes #4547)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 17 Jun 2019 21:30:08 +0200 |
parents | 8c794a694d66 |
children | ebe9aab81898 |
comparison
equal
deleted
inserted
replaced
17126:e35620f6d395 | 17127:d244a9be99db |
---|---|
933 if (v == NULL) | 933 if (v == NULL) |
934 break; | 934 break; |
935 v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX; | 935 v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX; |
936 } | 936 } |
937 | 937 |
938 if (isdefault) | 938 // Note: the values are copied directly to avoid alloc/free. |
939 v->di_tv = def_rettv; | 939 // "argvars" must have VAR_FIXED for v_lock. |
940 else | 940 v->di_tv = isdefault ? def_rettv : argvars[i]; |
941 // Note: the values are copied directly to avoid alloc/free. | |
942 // "argvars" must have VAR_FIXED for v_lock. | |
943 v->di_tv = argvars[i]; | |
944 v->di_tv.v_lock = VAR_FIXED; | 941 v->di_tv.v_lock = VAR_FIXED; |
945 | 942 |
946 if (addlocal) | 943 if (addlocal) |
947 { | 944 { |
948 /* Named arguments should be accessed without the "a:" prefix in | 945 /* Named arguments should be accessed without the "a:" prefix in |
1537 argv[i + argv_clear] = argvars_in[i]; | 1534 argv[i + argv_clear] = argvars_in[i]; |
1538 argvars = argv; | 1535 argvars = argv; |
1539 argcount = partial->pt_argc + argcount_in; | 1536 argcount = partial->pt_argc + argcount_in; |
1540 } | 1537 } |
1541 } | 1538 } |
1542 | |
1543 | 1539 |
1544 /* | 1540 /* |
1545 * Execute the function if executing and no errors were detected. | 1541 * Execute the function if executing and no errors were detected. |
1546 */ | 1542 */ |
1547 if (!evaluate) | 1543 if (!evaluate) |
3996 set_ref_in_previous_funccal(int copyID) | 3992 set_ref_in_previous_funccal(int copyID) |
3997 { | 3993 { |
3998 int abort = FALSE; | 3994 int abort = FALSE; |
3999 funccall_T *fc; | 3995 funccall_T *fc; |
4000 | 3996 |
4001 for (fc = previous_funccal; fc != NULL; fc = fc->caller) | 3997 for (fc = previous_funccal; !abort && fc != NULL; fc = fc->caller) |
4002 { | 3998 { |
4003 fc->fc_copyID = copyID + 1; | 3999 fc->fc_copyID = copyID + 1; |
4004 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, | 4000 abort = abort |
4005 NULL); | 4001 || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1, NULL) |
4006 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, | 4002 || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1, NULL) |
4007 NULL); | 4003 || set_ref_in_list(&fc->l_varlist, copyID + 1, NULL); |
4008 } | 4004 } |
4009 return abort; | 4005 return abort; |
4010 } | 4006 } |
4011 | 4007 |
4012 static int | 4008 static int |
4015 int abort = FALSE; | 4011 int abort = FALSE; |
4016 | 4012 |
4017 if (fc->fc_copyID != copyID) | 4013 if (fc->fc_copyID != copyID) |
4018 { | 4014 { |
4019 fc->fc_copyID = copyID; | 4015 fc->fc_copyID = copyID; |
4020 abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL); | 4016 abort = abort |
4021 abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL); | 4017 || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL) |
4022 abort = abort || set_ref_in_func(NULL, fc->func, copyID); | 4018 || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL) |
4019 || set_ref_in_list(&fc->l_varlist, copyID, NULL) | |
4020 || set_ref_in_func(NULL, fc->func, copyID); | |
4023 } | 4021 } |
4024 return abort; | 4022 return abort; |
4025 } | 4023 } |
4026 | 4024 |
4027 /* | 4025 /* |