Skip to content

Commit

Permalink
patch 9.0.1357: using null_object results in an internal error
Browse files Browse the repository at this point in the history
Problem:    Using null_object results in an internal error. (Ernie Rael)
Solution:   Add instructions for pushing an object and class. (closes #12044)
  • Loading branch information
brammool committed Feb 26, 2023
1 parent 4f026ea commit c4e1b86
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -3449,3 +3449,7 @@ EXTERN char e_using_null_object[]
#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
17 changes: 17 additions & 0 deletions src/testdir/test_vim9_class.vim
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,23 @@ def Test_class_defined_twice()
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
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1357,
/**/
1356,
/**/
Expand Down
3 changes: 3 additions & 0 deletions src/vim9.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ typedef enum {
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
Expand Down Expand Up @@ -518,6 +520,7 @@ struct isn_S {
channel_T *channel;
job_T *job;
partial_T *partial;
class_T *class;
jump_T jump;
jumparg_T jumparg;
forloop_T forloop;
Expand Down
21 changes: 19 additions & 2 deletions src/vim9execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1944,8 +1944,7 @@ exec_command(isn_T *iptr)
source_cookie_T cookie;

SOURCING_LNUM = iptr->isn_lnum;
// Pass getsourceline to get an error for a missing ":end"
// command.
// 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,
Expand Down Expand Up @@ -4018,6 +4017,8 @@ exec_instructions(ectx_T *ectx)
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);
Expand Down Expand Up @@ -4064,6 +4065,14 @@ exec_instructions(ectx_T *ectx)
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
Expand Down Expand Up @@ -6662,6 +6671,14 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
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;
Expand Down
48 changes: 47 additions & 1 deletion src/vim9instr.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,35 @@ generate_SETTYPE(
return OK;
}

/*
* 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.
Expand Down Expand Up @@ -718,6 +747,17 @@ generate_tv_PUSH(cctx_T *cctx, typval_T *tv)
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);
Expand Down Expand Up @@ -1937,7 +1977,8 @@ generate_PCALL(
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)
if (check_func_args_from_type(cctx, type, argcount, at_top, name)
== FAIL)
return FAIL;

ret_type = type->tt_member;
Expand Down Expand Up @@ -2467,6 +2508,10 @@ delete_instr(isn_T *isn)
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;
Expand Down Expand Up @@ -2659,6 +2704,7 @@ delete_instr(isn_T *isn)
case ISN_PUSHF:
case ISN_PUSHJOB:
case ISN_PUSHNR:
case ISN_PUSHOBJ:
case ISN_PUSHSPEC:
case ISN_PUT:
case ISN_REDIREND:
Expand Down

0 comments on commit c4e1b86

Please sign in to comment.