patch 9.0.2000: Vim9: use-after-free in deep call stack

Problem:  Vim9: use-after-free in deep call stack
Solution: Get the objct pointer from execution stack

closes: #13296

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 0c8fd70..0e70c9f 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -6989,4 +6989,44 @@
   call v9.CheckSourceSuccess(lines)
 endfunc
 
+" Test for recursively calling an object method.  This used to cause an
+" use-after-free error.
+def Test_recursive_object_method_call()
+  var lines =<< trim END
+    vim9script
+    class A
+      this.val: number = 0
+      def Foo(): number
+        if this.val >= 90
+          return this.val
+        endif
+        this.val += 1
+        return this.Foo()
+      enddef
+    endclass
+    var a = A.new()
+    assert_equal(90, a.Foo())
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for recursively calling a class method.
+def Test_recursive_class_method_call()
+  var lines =<< trim END
+    vim9script
+    class A
+      static val: number = 0
+      static def Foo(): number
+        if val >= 90
+          return val
+        endif
+        val += 1
+        return Foo()
+      enddef
+    endclass
+    assert_equal(90, A.Foo())
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index 8dea204..5d1c1c9 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2000,
+/**/
     1999,
 /**/
     1998,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index f237132..8262822 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -559,6 +559,12 @@
 				     arg_to_add + STACK_FRAME_SIZE + varcount))
 	return FAIL;
 
+    // The object pointer is in the execution typval stack.  The GA_GROW call
+    // above may have reallocated the execution typval stack.  So the object
+    // pointer may not be valid anymore.  Get the object pointer again from the
+    // execution stack.
+    obj = STACK_TV_BOT(0) - argcount - vararg_count - 1;
+
     // If depth of calling is getting too high, don't execute the function.
     if (funcdepth_increment() == FAIL)
 	return FAIL;