Mercurial > vim
comparison src/vim9execute.c @ 23330:e8eb4fd44902 v8.2.2208
patch 8.2.2208: Vim9: after reloading a script variable index may be invalid
Commit: https://github.com/vim/vim/commit/4aab88d919168ce2ddf4845482f4cff9efa52b5b
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Dec 24 21:56:41 2020 +0100
patch 8.2.2208: Vim9: after reloading a script variable index may be invalid
Problem: Vim9: after reloading a script variable index may be invalid.
Solution: When the sequence number doesn't match give an error for using a
script-local variable from a compiled function. (closes #7547)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 24 Dec 2020 22:00:04 +0100 |
parents | d9ae7dd3a0f2 |
children | 456d625bb8c1 |
comparison
equal
deleted
inserted
replaced
23329:2d0d83f002e8 | 23330:e8eb4fd44902 |
---|---|
1400 break; | 1400 break; |
1401 | 1401 |
1402 // load s: variable in Vim9 script | 1402 // load s: variable in Vim9 script |
1403 case ISN_LOADSCRIPT: | 1403 case ISN_LOADSCRIPT: |
1404 { | 1404 { |
1405 scriptitem_T *si = | 1405 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
1406 SCRIPT_ITEM(iptr->isn_arg.script.script_sid); | 1406 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) |
1407 + ectx.ec_dfunc_idx; | |
1408 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); | |
1407 svar_T *sv; | 1409 svar_T *sv; |
1408 | 1410 |
1409 sv = ((svar_T *)si->sn_var_vals.ga_data) | 1411 if (sref->sref_seq != si->sn_script_seq) |
1410 + iptr->isn_arg.script.script_idx; | 1412 { |
1413 // The script was reloaded after the function was | |
1414 // compiled, the script_idx may not be valid. | |
1415 semsg(_(e_script_variable_invalid_after_reload_in_function_str), | |
1416 dfunc->df_ufunc->uf_name_exp); | |
1417 goto failed; | |
1418 } | |
1419 sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx; | |
1411 allocate_if_null(sv->sv_tv); | 1420 allocate_if_null(sv->sv_tv); |
1412 if (GA_GROW(&ectx.ec_stack, 1) == FAIL) | 1421 if (GA_GROW(&ectx.ec_stack, 1) == FAIL) |
1413 goto failed; | 1422 goto failed; |
1414 copy_tv(sv->sv_tv, STACK_TV_BOT(0)); | 1423 copy_tv(sv->sv_tv, STACK_TV_BOT(0)); |
1415 ++ectx.ec_stack.ga_len; | 1424 ++ectx.ec_stack.ga_len; |
1614 break; | 1623 break; |
1615 | 1624 |
1616 // store script-local variable in Vim9 script | 1625 // store script-local variable in Vim9 script |
1617 case ISN_STORESCRIPT: | 1626 case ISN_STORESCRIPT: |
1618 { | 1627 { |
1619 scriptitem_T *si = SCRIPT_ITEM( | 1628 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
1620 iptr->isn_arg.script.script_sid); | 1629 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) |
1621 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) | 1630 + ectx.ec_dfunc_idx; |
1622 + iptr->isn_arg.script.script_idx; | 1631 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); |
1623 | 1632 svar_T *sv; |
1633 | |
1634 if (sref->sref_seq != si->sn_script_seq) | |
1635 { | |
1636 // The script was reloaded after the function was | |
1637 // compiled, the script_idx may not be valid. | |
1638 SOURCING_LNUM = iptr->isn_lnum; | |
1639 semsg(_(e_script_variable_invalid_after_reload_in_function_str), | |
1640 dfunc->df_ufunc->uf_name_exp); | |
1641 goto failed; | |
1642 } | |
1643 sv = ((svar_T *)si->sn_var_vals.ga_data) + sref->sref_idx; | |
1624 --ectx.ec_stack.ga_len; | 1644 --ectx.ec_stack.ga_len; |
1625 clear_tv(sv->sv_tv); | 1645 clear_tv(sv->sv_tv); |
1626 *sv->sv_tv = *STACK_TV_BOT(0); | 1646 *sv->sv_tv = *STACK_TV_BOT(0); |
1627 } | 1647 } |
1628 break; | 1648 break; |
3376 smsg("%4d LOADV v:%s", current, | 3396 smsg("%4d LOADV v:%s", current, |
3377 get_vim_var_name(iptr->isn_arg.number)); | 3397 get_vim_var_name(iptr->isn_arg.number)); |
3378 break; | 3398 break; |
3379 case ISN_LOADSCRIPT: | 3399 case ISN_LOADSCRIPT: |
3380 { | 3400 { |
3381 scriptitem_T *si = | 3401 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
3382 SCRIPT_ITEM(iptr->isn_arg.script.script_sid); | 3402 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); |
3383 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) | 3403 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) |
3384 + iptr->isn_arg.script.script_idx; | 3404 + sref->sref_idx; |
3385 | 3405 |
3386 smsg("%4d LOADSCRIPT %s-%d from %s", current, | 3406 smsg("%4d LOADSCRIPT %s-%d from %s", current, |
3387 sv->sv_name, | 3407 sv->sv_name, |
3388 iptr->isn_arg.script.script_idx, | 3408 sref->sref_idx, |
3389 si->sn_name); | 3409 si->sn_name); |
3390 } | 3410 } |
3391 break; | 3411 break; |
3392 case ISN_LOADS: | 3412 case ISN_LOADS: |
3393 { | 3413 { |
3476 iptr->isn_arg.loadstore.ls_name, si->sn_name); | 3496 iptr->isn_arg.loadstore.ls_name, si->sn_name); |
3477 } | 3497 } |
3478 break; | 3498 break; |
3479 case ISN_STORESCRIPT: | 3499 case ISN_STORESCRIPT: |
3480 { | 3500 { |
3481 scriptitem_T *si = | 3501 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
3482 SCRIPT_ITEM(iptr->isn_arg.script.script_sid); | 3502 scriptitem_T *si = SCRIPT_ITEM(sref->sref_sid); |
3483 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) | 3503 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) |
3484 + iptr->isn_arg.script.script_idx; | 3504 + sref->sref_idx; |
3485 | 3505 |
3486 smsg("%4d STORESCRIPT %s-%d in %s", current, | 3506 smsg("%4d STORESCRIPT %s-%d in %s", current, |
3487 sv->sv_name, | 3507 sv->sv_name, |
3488 iptr->isn_arg.script.script_idx, | 3508 sref->sref_idx, |
3489 si->sn_name); | 3509 si->sn_name); |
3490 } | 3510 } |
3491 break; | 3511 break; |
3492 case ISN_STOREOPT: | 3512 case ISN_STOREOPT: |
3493 smsg("%4d STOREOPT &%s", current, | 3513 smsg("%4d STOREOPT &%s", current, |