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 -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///