Mercurial > vim
diff src/vim9instr.c @ 32051:e8c60d35fce3 v9.0.1357
patch 9.0.1357: using null_object results in an internal error
Commit: https://github.com/vim/vim/commit/c4e1b86cb0d88fa5ec1141d3c600e026dcc1bc21
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 26 18:58:23 2023 +0000
patch 9.0.1357: using null_object results in an internal error
Problem: Using null_object results in an internal error. (Ernie Rael)
Solution: Add instructions for pushing an object and class. (closes https://github.com/vim/vim/issues/12044)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 26 Feb 2023 20:00:03 +0100 |
parents | f1a5e67e9a1b |
children | 76fd08a4ae1d |
line wrap: on
line diff
--- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -656,6 +656,35 @@ generate_SETTYPE( } /* + * 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,6 +747,17 @@ generate_tv_PUSH(cctx_T *cctx, typval_T 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,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; @@ -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; @@ -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: