# HG changeset patch
# User Petter T. <petter.vilhelm@gmail.com>
# Date 1704913501 -3600
#      Wed Jan 10 20:05:01 2024 +0100
# Branch bytecode-interpreter
# Node ID ff95ee9d5b8b88b4857e5b5729be7520ee252644
# Parent  875b80270e39d4eff93bdaf11b5c6f97d9685844
Fix nargin for scripts in bytecode interpreter (bug #65140)

So that nargin calls in scripts properly matches argv or amount of function
arguments, instead of always zero.

* stack-frame.cc: Set nargin
* test/compile/bytecode.tst: Do new test
* test/compile/bytecode_script_nargin.m: New test file
* test/compile/module.mk: Add new file

diff -r 875b80270e39 -r ff95ee9d5b8b libinterp/corefcn/stack-frame.cc
--- a/libinterp/corefcn/stack-frame.cc	Wed Jan 10 20:04:57 2024 +0100
+++ b/libinterp/corefcn/stack-frame.cc	Wed Jan 10 20:05:01 2024 +0100
@@ -1509,6 +1509,9 @@
     auto eval_frame = access_link ();
     auto parent_frame = static_link ();
 
+    // Set nargin to match the value of nargin in the eval frame
+    set_nargin (eval_frame->get_auto_fcn_var (stack_frame::NARGIN).int_value()); // TODO: Kinda wasteful fn calls
+
     bool caller_is_eval_frame = eval_frame == parent_frame;
     bool eval_frame_is_bytecode = eval_frame->is_bytecode_fcn_frame ();
 
diff -r 875b80270e39 -r ff95ee9d5b8b test/compile/bytecode.tst
--- a/test/compile/bytecode.tst	Wed Jan 10 20:04:57 2024 +0100
+++ b/test/compile/bytecode.tst	Wed Jan 10 20:05:01 2024 +0100
@@ -782,10 +782,31 @@
 %!   end
 %! end
 %!
+%! %% Test that nargin is set properly
+%!
+%! __vm_enable__ (0, "local");
+%! clear all
+%! bytecode_script_nargin_call_recursive = true; % The script calls it self once if this symbol is true
+%! bytecode_script_nargin_expected_value = nargin; % The expected value of nargin
+%! bytecode_script_nargin;
+%!
+%! % Call in top scope, to check that Octave cli start options set nargin to whatever the user started Octave with
+%! evalin ("base", "bytecode_script_nargin_call_recursive = true; bytecode_script_nargin_expected_value = nargin; bytecode_script_nargin;");
+%!
+%! % Call in function
+%! eval ("function foo (a,b) bytecode_script_nargin_expected_value = nargin; bytecode_script_nargin; end; foo (1, 2);")
+%!
+%! __vm_enable__ (1, "local");
+%! clear all
+%! bytecode_script_nargin_call_recursive = true;
+%! bytecode_script_nargin_expected_value = nargin;
+%! bytecode_script_nargin;
+%!
+%! evalin ("base", "bytecode_script_nargin_call_recursive = true; bytecode_script_nargin_expected_value = nargin; bytecode_script_nargin;");
+%! eval ("function foo (a,b) bytecode_script_nargin_expected_value = nargin; bytecode_script_nargin; end; foo (1, 2);")
+%!
 %! %% Cleanup after the tests
-%! clear global bytecode_script_topscope_call_self
-%! clear global bytecode_script_topscope_place
-%! clear bytecode_script_topscope_cli_fn
+%! clear all
 
 ## Test save() and load() from scripts.
 %!testif ENABLE_BYTECODE_EVALUATOR
diff -r 875b80270e39 -r ff95ee9d5b8b test/compile/bytecode_script_nargin.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compile/bytecode_script_nargin.m	Wed Jan 10 20:05:01 2024 +0100
@@ -0,0 +1,19 @@
+
+s_whos = whos;
+
+if length (s_whos)
+  s_whos = s_whos(end);
+
+  % Only in the top scope nargin is equal to the size of argv
+  if strcmp (s_whos.nesting.function, "top scope")
+    assert (length (argv ()) == nargin ())
+  end
+end
+
+assert (bytecode_script_nargin_expected_value == nargin)
+
+if exist ("bytecode_script_nargin_call_recursive") && bytecode_script_nargin_call_recursive
+  bytecode_script_nargin_call_recursive = false;
+  bytecode_script_nargin;
+  bytecode_script_nargin_call_recursive = true;
+end
diff -r 875b80270e39 -r ff95ee9d5b8b test/compile/module.mk
--- a/test/compile/module.mk	Wed Jan 10 20:04:57 2024 +0100
+++ b/test/compile/module.mk	Wed Jan 10 20:05:01 2024 +0100
@@ -28,6 +28,7 @@
   %reldir%/bytecode_range.m \
   %reldir%/bytecode_return.m \
   %reldir%/bytecode_scripts.m \
+  %reldir%/bytecode_script_nargin.m \
   %reldir%/bytecode_script_topscope.m \
   %reldir%/bytecode_script_topscope_assert.m \
   %reldir%/bytecode_script_topscope_setup.m \
