Mercurial > vim
comparison src/vim9compile.c @ 24796:7c1375eb1636 v8.2.2936
patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset
Commit: https://github.com/vim/vim/commit/5fa9b24440d677c1aa00084d0cf84638b1e1a0d5
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jun 4 21:00:32 2021 +0200
patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset
Problem: Vim9: converting number to bool uses wrong stack offset. (Salman
Halim)
Solution: Include the offset in the 2BOOL command.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 04 Jun 2021 21:15:04 +0200 |
parents | 7464d4c927f5 |
children | a8d64f1a223b |
comparison
equal
deleted
inserted
replaced
24795:05a337d1fe73 | 24796:7c1375eb1636 |
---|---|
575 } | 575 } |
576 | 576 |
577 /* | 577 /* |
578 * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING. | 578 * If type at "offset" isn't already VAR_STRING then generate ISN_2STRING. |
579 * But only for simple types. | 579 * But only for simple types. |
580 */ | 580 * When "tolerant" is TRUE convert most types to string, e.g. a List. |
581 static int | 581 */ |
582 may_generate_2STRING(int offset, cctx_T *cctx) | 582 static int |
583 may_generate_2STRING(int offset, int tolerant, cctx_T *cctx) | |
583 { | 584 { |
584 isn_T *isn; | 585 isn_T *isn; |
585 isntype_T isntype = ISN_2STRING; | 586 isntype_T isntype = ISN_2STRING; |
586 garray_T *stack = &cctx->ctx_type_stack; | 587 garray_T *stack = &cctx->ctx_type_stack; |
587 type_T **type; | 588 type_T **type; |
604 case VAR_ANY: | 605 case VAR_ANY: |
605 case VAR_UNKNOWN: | 606 case VAR_UNKNOWN: |
606 isntype = ISN_2STRING_ANY; | 607 isntype = ISN_2STRING_ANY; |
607 break; | 608 break; |
608 | 609 |
610 // conversion possible when tolerant | |
611 case VAR_LIST: | |
612 if (tolerant) | |
613 { | |
614 isntype = ISN_2STRING_ANY; | |
615 break; | |
616 } | |
617 // FALLTHROUGH | |
618 | |
609 // conversion not possible | 619 // conversion not possible |
610 case VAR_VOID: | 620 case VAR_VOID: |
611 case VAR_BLOB: | 621 case VAR_BLOB: |
612 case VAR_FUNC: | 622 case VAR_FUNC: |
613 case VAR_PARTIAL: | 623 case VAR_PARTIAL: |
614 case VAR_LIST: | |
615 case VAR_DICT: | 624 case VAR_DICT: |
616 case VAR_JOB: | 625 case VAR_JOB: |
617 case VAR_CHANNEL: | 626 case VAR_CHANNEL: |
618 case VAR_INSTR: | 627 case VAR_INSTR: |
619 to_string_error((*type)->tt_type); | 628 to_string_error((*type)->tt_type); |
621 } | 630 } |
622 | 631 |
623 *type = &t_string; | 632 *type = &t_string; |
624 if ((isn = generate_instr(cctx, isntype)) == NULL) | 633 if ((isn = generate_instr(cctx, isntype)) == NULL) |
625 return FAIL; | 634 return FAIL; |
626 isn->isn_arg.number = offset; | 635 isn->isn_arg.tostring.offset = offset; |
636 isn->isn_arg.tostring.tolerant = tolerant; | |
627 | 637 |
628 return OK; | 638 return OK; |
629 } | 639 } |
630 | 640 |
631 static int | 641 static int |
884 return OK; | 894 return OK; |
885 } | 895 } |
886 | 896 |
887 /* | 897 /* |
888 * Generate an ISN_2BOOL instruction. | 898 * Generate an ISN_2BOOL instruction. |
889 */ | 899 * "offset" is the offset in the type stack. |
890 static int | 900 */ |
891 generate_2BOOL(cctx_T *cctx, int invert) | 901 static int |
902 generate_2BOOL(cctx_T *cctx, int invert, int offset) | |
892 { | 903 { |
893 isn_T *isn; | 904 isn_T *isn; |
894 garray_T *stack = &cctx->ctx_type_stack; | 905 garray_T *stack = &cctx->ctx_type_stack; |
895 | 906 |
896 RETURN_OK_IF_SKIP(cctx); | 907 RETURN_OK_IF_SKIP(cctx); |
897 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) | 908 if ((isn = generate_instr(cctx, ISN_2BOOL)) == NULL) |
898 return FAIL; | 909 return FAIL; |
899 isn->isn_arg.number = invert; | 910 isn->isn_arg.tobool.invert = invert; |
911 isn->isn_arg.tobool.offset = offset; | |
900 | 912 |
901 // type becomes bool | 913 // type becomes bool |
902 ((type_T **)stack->ga_data)[stack->ga_len - 1] = &t_bool; | 914 ((type_T **)stack->ga_data)[stack->ga_len + offset] = &t_bool; |
903 | 915 |
904 return OK; | 916 return OK; |
905 } | 917 } |
906 | 918 |
907 /* | 919 /* |
1006 if (expected == &t_bool && actual != &t_bool | 1018 if (expected == &t_bool && actual != &t_bool |
1007 && (actual->tt_flags & TTFLAG_BOOL_OK)) | 1019 && (actual->tt_flags & TTFLAG_BOOL_OK)) |
1008 { | 1020 { |
1009 // Using "0", "1" or the result of an expression with "&&" or "||" as a | 1021 // Using "0", "1" or the result of an expression with "&&" or "||" as a |
1010 // boolean is OK but requires a conversion. | 1022 // boolean is OK but requires a conversion. |
1011 generate_2BOOL(cctx, FALSE); | 1023 generate_2BOOL(cctx, FALSE, offset); |
1012 return OK; | 1024 return OK; |
1013 } | 1025 } |
1014 | 1026 |
1015 where.wt_index = arg_idx; | 1027 where.wt_index = arg_idx; |
1016 where.wt_variable = FALSE; | 1028 where.wt_variable = FALSE; |
2780 if (need_type(*typep, &t_dict_any, -2, 0, cctx, | 2792 if (need_type(*typep, &t_dict_any, -2, 0, cctx, |
2781 FALSE, FALSE) == FAIL) | 2793 FALSE, FALSE) == FAIL) |
2782 return FAIL; | 2794 return FAIL; |
2783 *typep = &t_any; | 2795 *typep = &t_any; |
2784 } | 2796 } |
2785 if (may_generate_2STRING(-1, cctx) == FAIL) | 2797 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL) |
2786 return FAIL; | 2798 return FAIL; |
2787 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) | 2799 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) |
2788 return FAIL; | 2800 return FAIL; |
2789 } | 2801 } |
2790 else if (vartype == VAR_STRING) | 2802 else if (vartype == VAR_STRING) |
3623 isn->isn_type = ISN_PUSHS; | 3635 isn->isn_type = ISN_PUSHS; |
3624 isn->isn_arg.string = vim_strsave((char_u *)buf); | 3636 isn->isn_arg.string = vim_strsave((char_u *)buf); |
3625 } | 3637 } |
3626 if (isn->isn_type == ISN_PUSHS) | 3638 if (isn->isn_type == ISN_PUSHS) |
3627 key = isn->isn_arg.string; | 3639 key = isn->isn_arg.string; |
3628 else if (may_generate_2STRING(-1, cctx) == FAIL) | 3640 else if (may_generate_2STRING(-1, FALSE, cctx) == FAIL) |
3629 return FAIL; | 3641 return FAIL; |
3630 *arg = skipwhite(*arg); | 3642 *arg = skipwhite(*arg); |
3631 if (**arg != ']') | 3643 if (**arg != ']') |
3632 { | 3644 { |
3633 emsg(_(e_missing_matching_bracket_after_dict_key)); | 3645 emsg(_(e_missing_matching_bracket_after_dict_key)); |
4024 { | 4036 { |
4025 if (p[-1] == '!') | 4037 if (p[-1] == '!') |
4026 invert = !invert; | 4038 invert = !invert; |
4027 --p; | 4039 --p; |
4028 } | 4040 } |
4029 if (generate_2BOOL(cctx, invert) == FAIL) | 4041 if (generate_2BOOL(cctx, invert, -1) == FAIL) |
4030 return FAIL; | 4042 return FAIL; |
4031 } | 4043 } |
4032 } | 4044 } |
4033 *end = p; | 4045 *end = p; |
4034 return OK; | 4046 return OK; |
4847 { | 4859 { |
4848 generate_ppconst(cctx, ppconst); | 4860 generate_ppconst(cctx, ppconst); |
4849 ppconst->pp_is_const = FALSE; | 4861 ppconst->pp_is_const = FALSE; |
4850 if (*op == '.') | 4862 if (*op == '.') |
4851 { | 4863 { |
4852 if (may_generate_2STRING(-2, cctx) == FAIL | 4864 if (may_generate_2STRING(-2, FALSE, cctx) == FAIL |
4853 || may_generate_2STRING(-1, cctx) == FAIL) | 4865 || may_generate_2STRING(-1, FALSE, cctx) == FAIL) |
4854 return FAIL; | 4866 return FAIL; |
4855 generate_instr_drop(cctx, ISN_CONCAT, 1); | 4867 generate_instr_drop(cctx, ISN_CONCAT, 1); |
4856 } | 4868 } |
4857 else | 4869 else |
4858 generate_two_op(cctx, op); | 4870 generate_two_op(cctx, op); |
6418 if (dest_type == VAR_DICT && range) | 6430 if (dest_type == VAR_DICT && range) |
6419 { | 6431 { |
6420 emsg(e_cannot_use_range_with_dictionary); | 6432 emsg(e_cannot_use_range_with_dictionary); |
6421 return FAIL; | 6433 return FAIL; |
6422 } | 6434 } |
6423 if (dest_type == VAR_DICT && may_generate_2STRING(-1, cctx) == FAIL) | 6435 if (dest_type == VAR_DICT |
6436 && may_generate_2STRING(-1, FALSE, cctx) == FAIL) | |
6424 return FAIL; | 6437 return FAIL; |
6425 if (dest_type == VAR_LIST || dest_type == VAR_BLOB) | 6438 if (dest_type == VAR_LIST || dest_type == VAR_BLOB) |
6426 { | 6439 { |
6427 type_T *type; | 6440 type_T *type; |
6428 | 6441 |
8381 | 8394 |
8382 if (compile_expr0(&p, cctx) == FAIL) | 8395 if (compile_expr0(&p, cctx) == FAIL) |
8383 return NULL; | 8396 return NULL; |
8384 if (cctx->ctx_skip == SKIP_YES) | 8397 if (cctx->ctx_skip == SKIP_YES) |
8385 return p; | 8398 return p; |
8386 if (may_generate_2STRING(-1, cctx) == FAIL) | 8399 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL) |
8387 return NULL; | 8400 return NULL; |
8388 if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL) | 8401 if (generate_instr_drop(cctx, ISN_THROW, 1) == NULL) |
8389 return NULL; | 8402 return NULL; |
8390 | 8403 |
8391 return p; | 8404 return p; |
8616 ++count; | 8629 ++count; |
8617 } | 8630 } |
8618 p += 2; | 8631 p += 2; |
8619 if (compile_expr0(&p, cctx) == FAIL) | 8632 if (compile_expr0(&p, cctx) == FAIL) |
8620 return NULL; | 8633 return NULL; |
8621 may_generate_2STRING(-1, cctx); | 8634 may_generate_2STRING(-1, TRUE, cctx); |
8622 ++count; | 8635 ++count; |
8623 p = skipwhite(p); | 8636 p = skipwhite(p); |
8624 if (*p != '`') | 8637 if (*p != '`') |
8625 { | 8638 { |
8626 emsg(_(e_missing_backtick)); | 8639 emsg(_(e_missing_backtick)); |