Patch 9.0.1357
Problem:    Using null_object results in an internal error. (Ernie Rael)
Solution:   Add instructions for pushing an object and class. (closes #12044)
Files:      src/vim9instr.c, src/vim9.h, src/vim9execute.c, src/errors.h,
            src/testdir/test_vim9_class.vim


*** ../vim-9.0.1356/src/vim9instr.c     2023-02-08 20:55:23.932100744 +0000
--- src/vim9instr.c     2023-02-26 18:56:59.578783641 +0000
***************
*** 656,661 ****
--- 656,690 ----
  }
  
  /*
+  * Generate an ISN_PUSHOBJ instruction.  Object is always NULL.
+  */
+     static int
+ generate_PUSHOBJ(cctx_T *cctx)
+ {
+     RETURN_OK_IF_SKIP(cctx);
+     if (generate_instr_type(cctx, ISN_PUSHOBJ, &t_any) == NULL)
+       return FAIL;
+     return OK;
+ }
+ 
+ /*
+  * Generate an ISN_PUSHCLASS instruction.  "class" can be NULL.
+  */
+     static int
+ generate_PUSHCLASS(cctx_T *cctx, class_T *class)
+ {
+     RETURN_OK_IF_SKIP(cctx);
+     isn_T *isn = generate_instr_type(cctx, ISN_PUSHCLASS,
+                                 class == NULL ? &t_any : &class->class_type);
+     if (isn == NULL)
+       return FAIL;
+     isn->isn_arg.class = class;
+     if (class != NULL)
+       ++class->class_refcount;
+     return OK;
+ }
+ 
+ /*
   * Generate a PUSH instruction for "tv".
   * "tv" will be consumed or cleared.
   */
***************
*** 718,723 ****
--- 747,763 ----
            generate_PUSHS(cctx, &tv->vval.v_string);
            tv->vval.v_string = NULL;
            break;
+       case VAR_OBJECT:
+           if (tv->vval.v_object != NULL)
+           {
+               emsg(_(e_cannot_use_non_null_object));
+               return FAIL;
+           }
+           generate_PUSHOBJ(cctx);
+           break;
+       case VAR_CLASS:
+           generate_PUSHCLASS(cctx, tv->vval.v_class);
+           break;
        default:
            siemsg("constant type %d not supported", tv->v_type);
            clear_tv(tv);
***************
*** 1937,1943 ****
        ret_type = &t_any;
      else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
      {
!       if (check_func_args_from_type(cctx, type, argcount, at_top, name) == 
FAIL)
            return FAIL;
  
        ret_type = type->tt_member;
--- 1977,1984 ----
        ret_type = &t_any;
      else if (type->tt_type == VAR_FUNC || type->tt_type == VAR_PARTIAL)
      {
!       if (check_func_args_from_type(cctx, type, argcount, at_top, name)
!                                                                      == FAIL)
            return FAIL;
  
        ret_type = type->tt_member;
***************
*** 2467,2472 ****
--- 2508,2517 ----
            blob_unref(isn->isn_arg.blob);
            break;
  
+       case ISN_PUSHCLASS:
+           class_unref(isn->isn_arg.class);
+           break;
+ 
        case ISN_UCALL:
            vim_free(isn->isn_arg.ufunc.cuf_name);
            break;
***************
*** 2659,2664 ****
--- 2704,2710 ----
        case ISN_PUSHF:
        case ISN_PUSHJOB:
        case ISN_PUSHNR:
+       case ISN_PUSHOBJ:
        case ISN_PUSHSPEC:
        case ISN_PUT:
        case ISN_REDIREND:
*** ../vim-9.0.1356/src/vim9.h  2023-02-08 20:55:23.932100744 +0000
--- src/vim9.h  2023-02-26 17:46:14.830669916 +0000
***************
*** 101,106 ****
--- 101,108 ----
      ISN_PUSHFUNC,     // push func isn_arg.string
      ISN_PUSHCHANNEL,  // push NULL channel
      ISN_PUSHJOB,      // push NULL job
+     ISN_PUSHOBJ,      // push NULL object
+     ISN_PUSHCLASS,    // push class, uses isn_arg.class
      ISN_NEWLIST,      // push list from stack items, size is isn_arg.number
                        // -1 for null_list
      ISN_NEWDICT,      // push dict from stack items, size is isn_arg.number
***************
*** 518,523 ****
--- 520,526 ----
        channel_T           *channel;
        job_T               *job;
        partial_T           *partial;
+       class_T             *class;
        jump_T              jump;
        jumparg_T           jumparg;
        forloop_T           forloop;
*** ../vim-9.0.1356/src/vim9execute.c   2023-02-18 18:38:33.375180762 +0000
--- src/vim9execute.c   2023-02-26 18:11:02.893238075 +0000
***************
*** 1944,1951 ****
      source_cookie_T cookie;
  
      SOURCING_LNUM = iptr->isn_lnum;
!     // Pass getsourceline to get an error for a missing ":end"
!     // command.
      CLEAR_FIELD(cookie);
      cookie.sourcing_lnum = iptr->isn_lnum - 1;
      if (do_cmdline(iptr->isn_arg.string,
--- 1944,1950 ----
      source_cookie_T cookie;
  
      SOURCING_LNUM = iptr->isn_lnum;
!     // Pass getsourceline to get an error for a missing ":end" command.
      CLEAR_FIELD(cookie);
      cookie.sourcing_lnum = iptr->isn_lnum - 1;
      if (do_cmdline(iptr->isn_arg.string,
***************
*** 4018,4023 ****
--- 4017,4024 ----
            case ISN_PUSHFUNC:
            case ISN_PUSHCHANNEL:
            case ISN_PUSHJOB:
+           case ISN_PUSHOBJ:
+           case ISN_PUSHCLASS:
                if (GA_GROW_FAILS(&ectx->ec_stack, 1))
                    goto theend;
                tv = STACK_TV_BOT(0);
***************
*** 4064,4069 ****
--- 4065,4078 ----
                        tv->vval.v_job = NULL;
  #endif
                        break;
+                   case ISN_PUSHOBJ:
+                       tv->v_type = VAR_OBJECT;
+                       tv->vval.v_object = NULL;
+                       break;
+                   case ISN_PUSHCLASS:
+                       tv->v_type = VAR_CLASS;
+                       tv->vval.v_class = iptr->isn_arg.class;
+                       break;
                    default:
                        tv->v_type = VAR_STRING;
                        tv->vval.v_string = iptr->isn_arg.string == NULL
***************
*** 6662,6667 ****
--- 6671,6684 ----
                smsg("%s%4d PUSHJOB \"no process\"", pfx, current);
  #endif
                break;
+           case ISN_PUSHOBJ:
+               smsg("%s%4d PUSHOBJ null", pfx, current);
+               break;
+           case ISN_PUSHCLASS:
+               smsg("%s%4d PUSHCLASS %s", pfx, current,
+                       iptr->isn_arg.class == NULL ? "null"
+                                   : (char *)iptr->isn_arg.class->class_name);
+               break;
            case ISN_PUSHEXC:
                smsg("%s%4d PUSH v:exception", pfx, current);
                break;
*** ../vim-9.0.1356/src/errors.h        2023-02-19 20:49:35.159795893 +0000
--- src/errors.h        2023-02-26 18:13:09.153553042 +0000
***************
*** 3449,3451 ****
--- 3449,3455 ----
  #endif
  EXTERN char e_cannot_use_color_none_did_you_mean_none[]
        INIT(= N_("E1361: Cannot use color \"none\", did you mean \"NONE\"?"));
+ #ifdef FEAT_EVAL
+ EXTERN char e_cannot_use_non_null_object[]
+       INIT(= N_("E1362: Cannot use a non-null object"));
+ #endif
*** ../vim-9.0.1356/src/testdir/test_vim9_class.vim     2023-02-25 
19:59:27.892421722 +0000
--- src/testdir/test_vim9_class.vim     2023-02-26 18:56:34.450778164 +0000
***************
*** 186,191 ****
--- 186,208 ----
    source XclassTwice.vim
  enddef
  
+ def Test_returning_null_object()
+   # this was causing an internal error
+   var lines =<< trim END
+       vim9script
+ 
+       class BufferList
+           def Current(): any
+               return null_object
+           enddef
+       endclass
+ 
+       var buffers = BufferList.new()
+       echo buffers.Current()
+   END
+   v9.CheckScriptSuccess(lines)
+ enddef
+ 
  def Test_class_interface_wrong_end()
    var lines =<< trim END
        vim9script
*** ../vim-9.0.1356/src/version.c       2023-02-26 14:47:20.359108900 +0000
--- src/version.c       2023-02-26 18:57:29.750790434 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1357,
  /**/

-- 
A bad peace is better than a good war. - Yiddish Proverb

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20230226185848.0FC411C0B1F%40moolenaar.net.

Raspunde prin e-mail lui