changeset 23543:f90e429453fd v8.2.2314

patch 8.2.2314: Vim9: returning zero takes two instructions Commit: https://github.com/vim/vim/commit/299f3036ec21cc9735846b2e0dfdfc5a78b26c1c Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jan 8 20:53:09 2021 +0100 patch 8.2.2314: Vim9: returning zero takes two instructions Problem: Vim9: returning zero takes two instructions. Solution: Add ISN_RETURN_ZERO.
author Bram Moolenaar <Bram@vim.org>
date Fri, 08 Jan 2021 21:00:04 +0100
parents 4ad827c071b9
children f1518df5eefa
files src/testdir/test_vim9_disassemble.vim src/version.c src/vim9.h src/vim9compile.c src/vim9execute.c
diffstat 5 files changed, 42 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -117,8 +117,7 @@ def Test_disassemble_exec_expr()
         '\d 2STRING stack\[-1\]\_s*' ..
         '\d\+ PUSHS ".txt"\_s*' ..
         '\d\+ EXECCONCAT 4\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -134,8 +133,7 @@ def Test_disassemble_yank_range()
         '\d EXEC   norm! m\[jjm\]\_s*' ..
         '  :''\[,''\]yank\_s*' ..
         '\d EXEC   :''\[,''\]yank\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -149,8 +147,7 @@ def Test_disassemble_put_expr()
         ' :3put ="text"\_s*' ..
         '\d PUSHS "text"\_s*' ..
         '\d PUT = 3\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -164,8 +161,7 @@ def Test_disassemble_put_range()
         ' :$-2put a\_s*' ..
         '\d RANGE $-2\_s*' ..
         '\d PUT a range\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -273,8 +269,7 @@ def Test_disassemble_store_member()
         '\d\+ PUSHS "a"\_s*' ..
         '\d\+ LOAD $1\_s*' ..
         '\d\+ STOREDICT\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -297,8 +292,7 @@ def Test_disassemble_store_index()
         '\d LOAD $0\_s*' ..
         '\d MEMBER dd\_s*' ..
         '\d STOREINDEX\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -333,8 +327,7 @@ def Test_disassemble_list_assign()
         '\d\+ STORE $1\_s*' ..
         '\d\+ SLICE 2\_s*' ..
         '\d\+ STORE $2\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -362,8 +355,7 @@ def Test_disassemble_list_add()
         '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
         '\d\+ LISTAPPEND\_s*' ..
         '\d\+ DROP\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -390,8 +382,7 @@ def Test_disassemble_blob_add()
         '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
         '\d\+ BLOBAPPEND\_s*' ..
         '\d\+ DROP\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -580,8 +571,7 @@ def Test_disassemble_closure()
         '\d LOAD arg\[-1\]\_s*' ..
         '\d CONCAT\_s*' ..
         '\d STOREOUTER $0\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 
   res = execute('disass g:Get')
@@ -615,8 +605,7 @@ def Test_disassemble_pcall()
         '\d PCALL top (argc 1)\_s*' ..
         '\d PCALL end\_s*' ..
         '\d DROP\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -865,8 +854,7 @@ def Test_disassemble_function()
         '\d PUSHS "UserFunc"\_s*' ..
         '\d BCALL funcref(argc 1)\_s*' ..
         '\d STORE $2\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         instr)
 enddef
 
@@ -893,8 +881,7 @@ def Test_disassemble_channel()
         'var chan1: channel\_s*' ..
         '\d PUSHCHANNEL 0\_s*' ..
         '\d STORE $2\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         instr)
 enddef
 
@@ -966,8 +953,7 @@ def Test_nested_func()
         'echomsg "inner"\_s*' ..
         'enddef\_s*' ..
         '\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         instr)
 enddef
 
@@ -989,8 +975,7 @@ def Test_nested_def_list()
         '\d DEF /Info\_s*' ..
         'def /Info/\_s*' ..
         '\d DEF /Info/\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         instr)
 enddef
 
@@ -1122,8 +1107,7 @@ def Test_disassemble_for_loop_unpack()
         'endfor\_s*' ..
         '\d\+ JUMP -> 8\_s*' ..
         '\d\+ DROP\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         instr)
 enddef
 
@@ -1143,8 +1127,7 @@ def Test_disassemble_typecast()
         '\d NEWLIST size 2\_s*' ..
         '\d SETTYPE list<number>\_s*' ..
         '\d STORE $0\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN\_s*',
+        '\d RETURN 0\_s*',
         instr)
 enddef
 
@@ -1631,8 +1614,7 @@ def Test_dsassemble_falsy_op()
       'echo "" ?? "empty string"\_s*' ..
       '\d\+ PUSHS "empty string"\_s*' ..
       '\d\+ ECHO 1\_s*' ..
-      '\d\+ PUSHNR 0\_s*' ..
-      '\d\+ RETURN',
+      '\d\+ RETURN 0',
       res)
 enddef
 
@@ -1659,8 +1641,7 @@ def Test_disassemble_compare_const()
           'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
           '\d PUSHNR 42.*' ..
           '\d ECHO 1.*' ..
-          '\d PUSHNR 0.*' ..
-          '\d RETURN.*',
+          '\d RETURN 0',
           instr)
     else
       # condition false, function just returns
@@ -1668,8 +1649,7 @@ def Test_disassemble_compare_const()
           'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
           'echo 42[ \n]*' ..
           'endif[ \n]*' ..
-          '\s*\d PUSHNR 0.*' ..
-          '\d RETURN.*',
+          '\d RETURN 0',
           instr)
     endif
 
@@ -1707,8 +1687,7 @@ def Test_disassemble_execute()
         '\d\+ LOAD $1\_s*' ..
         '\d\+ CONCAT\_s*' ..
         '\d\+ EXECUTE 1\_s*' ..
-        '\d\+ PUSHNR 0\_s*' ..
-        '\d\+ RETURN',
+        '\d\+ RETURN 0',
         res)
 enddef
 
@@ -1727,8 +1706,7 @@ def Test_disassemble_echomsg()
         "echoerr 'went' .. 'wrong'\\_s*" ..
         '\d PUSHS "wentwrong"\_s*' ..
         '\d ECHOERR 1\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -1837,8 +1815,7 @@ def Test_shuffle()
         '\d SHUFFLE 2 up 1\_s*' ..
         '\d BCALL append(argc 2)\_s*' ..
         '\d DROP\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
@@ -1861,8 +1838,7 @@ def Test_silent()
         '\d PUSHS "error"\_s*' ..
         '\d ECHOERR 1\_s*' ..
         '\d CMDMOD_REV\_s*' ..
-        '\d PUSHNR 0\_s*' ..
-        '\d RETURN',
+        '\d RETURN 0',
         res)
 enddef
 
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2314,
+/**/
     2313,
 /**/
     2312,
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -84,6 +84,7 @@ typedef enum {
     ISN_PCALL,	    // call partial, use isn_arg.pfunc
     ISN_PCALL_END,  // cleanup after ISN_PCALL with cpf_top set
     ISN_RETURN,	    // return, result is on top of stack
+    ISN_RETURN_ZERO, // Push zero, then return
     ISN_FUNCREF,    // push a function ref to dfunc isn_arg.funcref
     ISN_NEWFUNC,    // create a global function from a lambda function
     ISN_DEF,	    // list functions
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -8190,8 +8190,7 @@ nextline:
 	}
 
 	// Return zero if there is no return at the end.
-	generate_PUSHNR(&cctx, 0);
-	generate_instr(&cctx, ISN_RETURN);
+	generate_instr(&cctx, ISN_RETURN_ZERO);
     }
 
     {
@@ -8483,6 +8482,7 @@ delete_instr(isn_T *isn)
 	case ISN_PUSHSPEC:
 	case ISN_PUT:
 	case ISN_RETURN:
+	case ISN_RETURN_ZERO:
 	case ISN_SHUFFLE:
 	case ISN_SLICE:
 	case ISN_STORE:
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2205,6 +2205,16 @@ call_def_function(
 		break;
 
 	    // return from a :def function call
+	    case ISN_RETURN_ZERO:
+		if (GA_GROW(&ectx.ec_stack, 1) == FAIL)
+		    goto failed;
+		tv = STACK_TV_BOT(0);
+		++ectx.ec_stack.ga_len;
+		tv->v_type = VAR_NUMBER;
+		tv->vval.v_number = 0;
+		tv->v_lock = 0;
+		// FALLTHROUGH
+
 	    case ISN_RETURN:
 		{
 		    garray_T	*trystack = &ectx.ec_trystack;
@@ -3804,6 +3814,9 @@ ex_disassemble(exarg_T *eap)
 	    case ISN_RETURN:
 		smsg("%4d RETURN", current);
 		break;
+	    case ISN_RETURN_ZERO:
+		smsg("%4d RETURN 0", current);
+		break;
 	    case ISN_FUNCREF:
 		{
 		    funcref_T	*funcref = &iptr->isn_arg.funcref;