Patch 8.2.1867
Problem:    Vim9: argument to add() not checked for blob.
Solution:   Add the BLOBAPPEND instruction.
Files:      src/vim9.h, src/vim9compile.c, src/vim9execute.c, src/errors.h,
            src/testdir/test_vim9_func.vim,
            src/testdir/test_vim9_disassemble.vim


*** ../vim-8.2.1866/src/vim9.h  2020-10-19 19:02:36.853261655 +0200
--- src/vim9.h  2020-10-19 20:23:16.084142073 +0200
***************
*** 126,131 ****
--- 126,132 ----
      ISN_ANYINDEX,   // [expr] runtime index
      ISN_ANYSLICE,   // [expr:expr] runtime slice
      ISN_SLICE,            // drop isn_arg.number items from start of list
+     ISN_BLOBAPPEND, // append to a blob, like add()
      ISN_GETITEM,    // push list item, isn_arg.number is the index
      ISN_MEMBER,           // dict[member]
      ISN_STRINGMEMBER, // dict.member using isn_arg.string
*** ../vim-8.2.1866/src/vim9compile.c   2020-10-19 19:02:36.857261645 +0200
--- src/vim9compile.c   2020-10-19 20:39:10.545495598 +0200
***************
*** 1521,1526 ****
--- 1521,1548 ----
  }
  
  /*
+  * Generate an ISN_BLOBAPPEND instruction.  Works like add().
+  * Argument count is already checked.
+  */
+     static int
+ generate_BLOBAPPEND(cctx_T *cctx)
+ {
+     garray_T  *stack = &cctx->ctx_type_stack;
+     type_T    *item_type;
+ 
+     // Caller already checked that blob_type is a blob.
+     item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
+     if (need_type(item_type, &t_number, -1, cctx, FALSE, FALSE) == FAIL)
+       return FAIL;
+ 
+     if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
+       return FAIL;
+ 
+     --stack->ga_len;      // drop the argument
+     return OK;
+ }
+ 
+ /*
   * Generate an ISN_DCALL or ISN_UCALL instruction.
   * Return FAIL if the number of arguments is wrong.
   */
***************
*** 2570,2582 ****
                type_T      *type = ((type_T **)stack->ga_data)[
                                                            stack->ga_len - 2];
  
-               // TODO: also check for VAR_BLOB
                if (type->tt_type == VAR_LIST)
                {
                    // inline "add(list, item)" so that the type can be checked
                    res = generate_LISTAPPEND(cctx);
                    idx = -1;
                }
            }
  
            if (idx >= 0)
--- 2592,2609 ----
                type_T      *type = ((type_T **)stack->ga_data)[
                                                            stack->ga_len - 2];
  
                if (type->tt_type == VAR_LIST)
                {
                    // inline "add(list, item)" so that the type can be checked
                    res = generate_LISTAPPEND(cctx);
                    idx = -1;
                }
+               else if (type->tt_type == VAR_BLOB)
+               {
+                   // inline "add(blob, nr)" so that the type can be checked
+                   res = generate_BLOBAPPEND(cctx);
+                   idx = -1;
+               }
            }
  
            if (idx >= 0)
***************
*** 5421,5427 ****
                        generate_PUSHS(cctx, NULL);
                        break;
                    case VAR_BLOB:
!                       generate_PUSHBLOB(cctx, NULL);
                        break;
                    case VAR_FUNC:
                        generate_PUSHFUNC(cctx, NULL, &t_func_void);
--- 5448,5454 ----
                        generate_PUSHS(cctx, NULL);
                        break;
                    case VAR_BLOB:
!                       generate_PUSHBLOB(cctx, blob_alloc());
                        break;
                    case VAR_FUNC:
                        generate_PUSHFUNC(cctx, NULL, &t_func_void);
***************
*** 7675,7680 ****
--- 7702,7708 ----
        case ISN_ANYINDEX:
        case ISN_ANYSLICE:
        case ISN_BCALL:
+       case ISN_BLOBAPPEND:
        case ISN_CATCH:
        case ISN_CHECKLEN:
        case ISN_CHECKNR:
*** ../vim-8.2.1866/src/vim9execute.c   2020-10-19 19:02:36.857261645 +0200
--- src/vim9execute.c   2020-10-19 20:31:23.638775112 +0200
***************
*** 2312,2317 ****
--- 2312,2340 ----
                }
                break;
  
+           case ISN_BLOBAPPEND:
+               {
+                   typval_T    *tv1 = STACK_TV_BOT(-2);
+                   typval_T    *tv2 = STACK_TV_BOT(-1);
+                   blob_T      *b = tv1->vval.v_blob;
+                   int         error = FALSE;
+                   varnumber_T n;
+ 
+                   // add a number to a blob
+                   if (b == NULL)
+                   {
+                       SOURCING_LNUM = iptr->isn_lnum;
+                       emsg(_(e_cannot_add_to_null_blob));
+                       goto on_error;
+                   }
+                   n = tv_get_number_chk(tv2, &error);
+                   if (error)
+                       goto on_error;
+                   ga_append(&b->bv_ga, (int)n);
+                   --ectx.ec_stack.ga_len;
+               }
+               break;
+ 
            // Computation with two arguments of unknown type
            case ISN_OPANY:
                {
***************
*** 3432,3437 ****
--- 3455,3461 ----
            case ISN_STRINDEX: smsg("%4d STRINDEX", current); break;
            case ISN_STRSLICE: smsg("%4d STRSLICE", current); break;
            case ISN_LISTAPPEND: smsg("%4d LISTAPPEND", current); break;
+           case ISN_BLOBAPPEND: smsg("%4d BLOBAPPEND", current); break;
            case ISN_LISTINDEX: smsg("%4d LISTINDEX", current); break;
            case ISN_LISTSLICE: smsg("%4d LISTSLICE", current); break;
            case ISN_ANYINDEX: smsg("%4d ANYINDEX", current); break;
*** ../vim-8.2.1866/src/errors.h        2020-10-19 19:02:36.857261645 +0200
--- src/errors.h        2020-10-19 20:28:56.595184155 +0200
***************
*** 284,287 ****
--- 284,289 ----
        INIT(= N_("E1129: Throw with empty string"));
  EXTERN char e_cannot_add_to_null_list[]
        INIT(= N_("E1130: Cannot add to null list"));
+ EXTERN char e_cannot_add_to_null_blob[]
+       INIT(= N_("E1131: Cannot add to null blob"));
  #endif
*** ../vim-8.2.1866/src/testdir/test_vim9_func.vim      2020-10-19 
20:20:59.892531346 +0200
--- src/testdir/test_vim9_func.vim      2020-10-19 20:34:41.466227816 +0200
***************
*** 1791,1799 ****
  enddef
  
  def Test_blob_add()
!   var b: blob = 0z12
!   add(b, 0x34)
!   assert_equal(0z1234, b)
  enddef
  
  def SID(): number
--- 1791,1815 ----
  enddef
  
  def Test_blob_add()
!   var b1: blob = 0z12
!   add(b1, 0x34)
!   assert_equal(0z1234, b1)
! 
!   var b2: blob # defaults to empty blob
!   add(b2, 0x67)
!   assert_equal(0z67, b2)
! 
!   var lines =<< trim END
!       var b: blob
!       add(b, "x")
!   END
!   CheckDefFailure(lines, 'E1012:', 2)
! 
!   lines =<< trim END
!       var b: blob = test_null_blob()
!       add(b, 123)
!   END
!   CheckDefExecFailure(lines, 'E1131:', 2)
  enddef
  
  def SID(): number
*** ../vim-8.2.1866/src/testdir/test_vim9_disassemble.vim       2020-10-19 
19:02:36.857261645 +0200
--- src/testdir/test_vim9_disassemble.vim       2020-10-19 20:42:37.773018704 
+0200
***************
*** 301,306 ****
--- 301,334 ----
          res)
  enddef
  
+ def s:BlobAdd()
+   var b: blob = 0z
+   add(b, 123)
+   add(b, g:aNumber)
+ enddef
+ 
+ def Test_disassemble_blob_add()
+   var res = execute('disass s:BlobAdd')
+   assert_match('<SNR>\d*_BlobAdd\_s*' ..
+         'var b: blob = 0z\_s*' ..
+         '\d PUSHBLOB 0z\_s*' ..
+         '\d STORE $0\_s*' ..
+         'add(b, 123)\_s*' ..
+         '\d LOAD $0\_s*' ..
+         '\d PUSHNR 123\_s*' ..
+         '\d BLOBAPPEND\_s*' ..
+         '\d DROP\_s*' ..
+         'add(b, g:aNumber)\_s*' ..
+         '\d LOAD $0\_s*' ..
+         '\d\+ LOADG g:aNumber\_s*' ..
+         '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
+         '\d\+ BLOBAPPEND\_s*' ..
+         '\d\+ DROP\_s*' ..
+         '\d\+ PUSHNR 0\_s*' ..
+         '\d\+ RETURN',
+         res)
+ enddef
+ 
  def s:ScriptFuncUnlet()
    g:somevar = "value"
    unlet g:somevar
*** ../vim-8.2.1866/src/version.c       2020-10-19 20:20:59.892531346 +0200
--- src/version.c       2020-10-19 20:24:02.828009395 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     1867,
  /**/

-- 
A fool learns from his mistakes, a wise man from someone else's.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202010191846.09JIk6Qr1210541%40masaka.moolenaar.net.

Raspunde prin e-mail lui