Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call_sv's docs are misleading #13481

Closed
p5pRT opened this issue Dec 19, 2013 · 22 comments
Closed

call_sv's docs are misleading #13481

p5pRT opened this issue Dec 19, 2013 · 22 comments
Labels

Comments

@p5pRT
Copy link

p5pRT commented Dec 19, 2013

Migrated from rt.perl.org#120826 (status was 'resolved')

Searchable as RT120826$

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2013

From @bulk88

Created by @bulk88

call_sv's docs currently say

---------------------------------------------------------------
=for apidoc p||call_sv

Performs a callback to the Perl sub whose name is in the SV. See
L<perlcall>.

=cut
---------------------------------------------------------------

That says it is exactly equivalent to "call_pv(SvPV_nolen(sv),0);"

perlcall says "This allows you to specify the Perl subroutine to be
called either as a C string (which has first been converted to an SV) or
a reference to a subroutine."

So my question is, what is the all inclusive list of what call_sv can be
used on? And more specifically, will call_sv take a CV *? Not a SV * ref
to a CV *, but a CV *?

I put a warn on SvTYPE into XS-APITest,

------------------------------------------------------
  Creating library ..\..\lib\auto\XS\APItest\APItest.lib and object
..\..\lib\a
uto\XS\APItest\APItest.exp
Generating code
Finished generating code
  if exist ..\..\lib\auto\XS\APItest\APItest.dll.manifest mt
-nologo -mani
fest ..\..\lib\auto\XS\APItest\APItest.dll.manifest
-outputresource​:..\..\lib\au
to\XS\APItest\APItest.dll;2
  if exist ..\..\lib\auto\XS\APItest\APItest.dll.manifest del
..\..\lib\au
to\XS\APItest\APItest.dll.manifest
  C​:\p519\src\miniperl.exe "-I..\..\lib" "-I..\..\lib"
-MExtUtils​::Command
  -e chmod -- 755 ..\..\lib\auto\XS\APItest\APItest.dll
  ..\..\perl.exe "-I..\..\lib" "-I..\..\lib"
"-MExtUtils​::Command​::MM" "-M
Test​::Harness" "-e" "undef *Test​::Harness​::Switches; test_harness(0,
'..\..\lib'
, '..\..\lib')" t/*.t
t/addissub.t ................. ok
t/arrayexpr.t ................ ok
t/autoload.t ................. ok
t/blockasexpr.t .............. ok
t/blockhooks-csc.t ........... ok
t/blockhooks.t ............... ok
t/call.t ..................... type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 10 - 0 args, G_VOID G_EVAL call_sv('d') - warning at
t/call.t line
  97
# got "type of SV is 3\n"
# expected ""
# Failed test 22 - 0 args, G_VOID G_KEEPERR G_EVAL call_sv('d') -
warning at t/c
all.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 47 - 3 args, G_VOID G_EVAL call_sv('d') - warning at
t/call.t line
  97
# got "type of SV is 3\n"
# expected ""
# Failed test 59 - 3 args, G_VOID G_KEEPERR G_EVAL call_sv('d') -
warning at t/c
all.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 84 - 0 args, G_SCALAR G_EVAL call_sv('d') - warning at
t/call.t li
ne 97
# got "type of SV is 3\n"
# expected ""
# Failed test 96 - 0 args, G_SCALAR G_KEEPERR G_EVAL call_sv('d') -
warning at t
/call.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 121 - 3 args, G_SCALAR G_EVAL call_sv('d') - warning at
t/call.t l
ine 97
# got "type of SV is 3\n"
# expected ""
# Failed test 133 - 3 args, G_SCALAR G_KEEPERR G_EVAL call_sv('d') -
warning at
t/call.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 158 - 0 args, G_ARRAY G_EVAL call_sv('d') - warning at
t/call.t li
ne 97
# got "type of SV is 3\n"
# expected ""
# Failed test 170 - 0 args, G_ARRAY G_KEEPERR G_EVAL call_sv('d') -
warning at t
/call.t line 97
t/call.t ..................... 1/436 # got "type of SV is 3\n\t(in
cleanup)
  its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 195 - 3 args, G_ARRAY G_EVAL call_sv('d') - warning at
t/call.t li
ne 97
# got "type of SV is 3\n"
# expected ""
# Failed test 207 - 3 args, G_ARRAY G_KEEPERR G_EVAL call_sv('d') -
warning at t
/call.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 232 - 0 args, G_DISCARD G_EVAL call_sv('d') - warning at
t/call.t
line 97
# got "type of SV is 3\n"
# expected ""
# Failed test 244 - 0 args, G_DISCARD G_KEEPERR G_EVAL call_sv('d') -
warning at
  t/call.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
type of SV is 1
type of SV is 9
type of SV is 3
# Failed test 269 - 3 args, G_DISCARD G_EVAL call_sv('d') - warning at
t/call.t
line 97
# got "type of SV is 3\n"
# expected ""
# Failed test 281 - 3 args, G_DISCARD G_KEEPERR G_EVAL call_sv('d') -
warning at
  t/call.t line 97
# got "type of SV is 3\n\t(in cleanup) its_dead_jim\n"
# expected "\t(in cleanup) its_dead_jim\n"
type of SV is 3
type of SV is 3
# Failed test 300 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 302 - at t/call.t line 176
# got "type of SV is 1\n"
# expected ""
# Failed test 304 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 306 - at t/call.t line 176
# got "type of SV is 1\n"
# expected ""
# Failed test 308 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 310 - at t/call.t line 176
# got "type of SV is 1\n"
# expected ""
# Failed test 312 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 314 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) aabbcc\n"
# expected "\t(in cleanup) aabbcc\n"
# Failed test 316 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 318 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) aabbcc\n"
# expected "\t(in cleanup) aabbcc\n"
# Failed test 320 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 322 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) aabbcc\n"
# expected "\t(in cleanup) aabbcc\n"
# Failed test 324 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 326 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) ARRAY(0x1badb2c)"
# expected "\t(in cleanup) ARRAY(0x1badb2c)"
# Failed test 328 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 330 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) ARRAY(0x1badb2c)"
# expected "\t(in cleanup) ARRAY(0x1badb2c)"
# Failed test 332 - at t/call.t line 170
# got "type of SV is 1\n"
# expected ""
# Failed test 334 - at t/call.t line 176
# got "type of SV is 1\n\t(in cleanup) ARRAY(0x1badb2c)"
# expected "\t(in cleanup) ARRAY(0x1badb2c)"
# Failed test 335 - at t/call.t line 185
# got "type of SV is 1\n"
# expected ""
# Failed test 336 - at t/call.t line 193
# got "type of SV is 1\n\t(in cleanup) aa\n"
# expected "\t(in cleanup) aa\n"
# Failed test 420 - call_sv('f99', G_EVAL|G_ARRAY|0) - __WARN__ not
called at t/
call.t line 274
# got "type of SV is 3\n"
# expected undef
# Failed test 426 - call_sv('f99', G_EVAL|G_ARRAY|G_KEEPERR) - the
correct error
  message at t/call.t line 277
# got 'type of SV is 3
# '
# expected /(?^​:^$)/
# Failed test 429 - call_sv('d', G_EVAL|G_ARRAY|0) - __WARN__ not called
at t/ca
ll.t line 274
# got "type of SV is 3\n"
# expected undef
t/call.t ..................... Failed 39/436 subtests
t/call_checker.t ............. ok
t/caller.t ................... ok
t/callregexec.t .............. ok
t/check_warnings.t ........... ok
t/cleanup.t .................. ok
t/clone-with-stack.t ......... ok
t/cophh.t .................... ok
t/coplabel.t ................. ok
t/copstash.t ................. ok
t/copyhints.t ................ ok
t/customop.t ................. ok
t/eval-filter.t .............. ok
t/exception.t ................ ok
t/fetch_pad_names.t .......... ok
t/gotosub.t .................. ok
t/grok.t ..................... ok
t/gv_autoload4.t ............. ok
t/gv_fetchmeth.t ............. ok
t/gv_fetchmeth_autoload.t .... ok
t/gv_fetchmethod_flags.t ..... ok
t/gv_init.t .................. ok
t/handy.t .................... ok
t/hash.t ..................... ok
t/keyword_multiline.t ........ ok
t/keyword_plugin.t ........... ok
t/labelconst.t ............... ok
t/lexsub.t ................... ok
t/loopblock.t ................ ok
t/looprest.t ................. ok
t/lvalue.t ................... ok
t/magic.t .................... ok
t/magic_chain.t .............. ok
t/mro.t ...................... ok
t/multicall.t ................ ok
t/my_cxt.t ................... ok
t/my_exit.t .................. Can't locate test.pl in @​INC (@​INC
contains​: C​:\p
519\src\lib ..\..\lib C​:/p519/src/lib .) at t/my_exit.t line 6.
t/my_exit.t .................. Dubious, test returned 2 (wstat 512, 0x200)
No subtests run
t/newCONSTSUB.t .............. ok
t/op.t ....................... ok
t/op_contextualize.t ......... ok
t/op_list.t .................. ok
t/overload.t ................. ok
t/pad_scalar.t ............... ok
t/peep.t ..................... ok
t/pmflag.t ................... ok
t/postinc.t .................. ok
t/printf.t ................... ok
t/ptr_table.t ................ ok
t/push.t ..................... ok
t/refs.t ..................... ok
t/rmagical.t ................. ok
t/rv2cv_op_cv.t .............. ok
t/savehints.t ................ ok
t/scopelessblock.t ........... ok
t/sort.t ..................... ok
t/stmtasexpr.t ............... ok
t/stmtsasexpr.t .............. ok
t/stuff_modify_bug.t ......... ok
t/stuff_svcur_bug.t .......... ok
t/subcall.t .................. ok
t/sviscow.t .................. ok
t/svpeek.t ................... ok
t/svpv.t ..................... ok
t/svpv_magic.t ............... ok
t/svsetsv.t .................. ok
t/swaplabel.t ................ ok
t/swaptwostmts.t ............. ok
t/sym-hook.t ................. ok
t/temp_lv_sub.t .............. ok
t/underscore_length.t ........ ok
t/utf16_to_utf8.t ............ ok
t/utf8.t ..................... ok
t/whichsig.t ................. ok
t/xs_special_subs.t .......... ok
t/xs_special_subs_require.t .. ok
t/xsub_h.t ................... ok

Test Summary Report
-------------------
t/call.t (Wstat​: 0 Tests​: 436 Failed​: 39)
  Failed tests​: 10, 22, 47, 59, 84, 96, 121, 133, 158, 170
  195, 207, 232, 244, 269, 281, 300, 302
  304, 306, 308, 310, 312, 314, 316, 318
  320, 322, 324, 326, 328, 330, 332, 334-336
  420, 426, 429
t/my_exit.t (Wstat​: 512 Tests​: 0 Failed​: 0)
  Non-zero exit status​: 2
  Parse errors​: No plan found in TAP output
Files=82, Tests=58285, 51 wallclock secs ( 7.30 usr + 3.64 sys = 10.94 CPU)
Result​: FAIL
Failed 2/82 test programs. 39/58285 subtests failed.
NMAKE : fatal error U1077​: '..\..\perl.exe' : return code '0xff'
Stop.

C​:\p519\src\ext\XS-APItest>
------------------------------------------------------

I got types as far as I can see. 1 (SVt_IV, probably these are refs to
things), 3 (SVt_PV), and 9 (SVt_PVGV, not sure what this is in Pure
Perl). NO 13 (SVt_PVCV). The tests are all from a very thin wrapper XSUB
  around the C call_sv. The sub SV * always comes from @​_ in the tests,
so whether a CV * is allowed is never tested. AFAIK, it is not possible
to put a CV * on @​_ stack from pure perl, is this correct?

The pod needs fixes. I'm still researching whether to add something to
APITest to test if CV *s can be passed to call_sv.

Perl Info

Flags:
     category=docs
     severity=low

Site configuration information for perl 5.19.7:

Configured by Owner at Thu Nov 28 02:32:44 2013.

Summary of my perl5 (revision 5 version 19 subversion 7) configuration:
   Derived from: 8f47723e28b75530b743941cdd8b07f849ec48e2
   Ancestor: 1061065f7a09399eefb50e9a035502621722bcc0
   Platform:
     osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
     uname=''
     config_args='undef'
     hint=recommended, useposix=true, d_sigaction=undef
     useithreads=define, usemultiplicity=define
     useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
     use64bitint=undef, use64bitall=undef, uselongdouble=undef
     usemymalloc=n, bincompat5005=undef
   Compiler:
     cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG -G7 -GL 
-DWIN32 -D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS 
-DPERL_HASH_FUNC_ONE_AT_A_TIME -DPERL_IMPLICIT_CONTEXT 
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T',
     optimize='-O1 -MD -Zi -DNDEBUG -G7 -GL',
     cppflags='-DWIN32'
     ccversion='13.10.6030', gccversion='', gccosandvers=''
     intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
     d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
     ivtype='long', ivsize=4, nvtype='double', nvsize=8, 
Off_t='__int64', lseeksize=8
     alignbytes=8, prototype=define
   Linker and Libraries:
     ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf 
-ltcg  -libpath:"c:\perl519\lib\CORE"  -machine:x86'
     libpth="C:\Program Files\Microsoft Visual Studio .NET 2003\VC7\lib"
     libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib 
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib 
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib 
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
     perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib 
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib 
oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib 
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
     libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl519.lib
     gnulibc_version=''
   Dynamic Linking:
     dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
     cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug 
-opt:ref,icf -ltcg  -libpath:"c:\perl519\lib\CORE"  -machine:x86'

Locally applied patches:
     uncommitted-changes
     8f47723e28b75530b743941cdd8b07f849ec48e2


@INC for perl 5.19.7:
     C:/perl519/site/lib
     C:/perl519/lib
     .


Environment for perl 5.19.7:
     HOME (unset)
     LANG (unset)
     LANGUAGE (unset)
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     PATH=C:\perl519\bin;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\IDE;C:\Program Files\Microsoft Visual Studio .NET 
2003\VC7\BIN;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools;C:\Program Files\Microsoft Visual Studio .NET 
2003\Common7\Tools\bin\prerelease;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem;
     PERL_BADLANG (unset)
     SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2013

From @ikegami

On Thu, Dec 19, 2013 at 4​:47 AM, bulk88 <perlbug-followup@​perl.org> wrote​:

# New Ticket Created by bulk88
# Please include the string​: [perl #120826]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=120826 >

This is a bug report for perl from bulk88@​hotmail.com,
generated with the help of perlbug 1.39 running under perl 5.19.7.

-----------------------------------------------------------------
[Please describe your issue here]

call_sv's docs currently say

---------------------------------------------------------------
=for apidoc p||call_sv

Performs a callback to the Perl sub whose name is in the SV. See
L<perlcall>.

=cut
---------------------------------------------------------------

That says it is exactly equivalent to "call_pv(SvPV_nolen(sv),0);"

perlcall says "This allows you to specify the Perl subroutine to be
called either as a C string (which has first been converted to an SV) or
a reference to a subroutine."

So my question is, what is the all inclusive list of what call_sv can be
used on? And more specifically, will call_sv take a CV *? Not a SV * ref
to a CV *, but a CV *?

[Assumes neither G_METHOD nor G_METHOD_NAMED was provided as a flag.]

A comment in the source says "May be called with any of a CV, a GV, or an
SV containing the name."

But it also accepts a code reference. Specifically, when neither G_METHOD
nor G_METHOD_NAMED was provided as a flag, it takes whatever pp_entersub
takes.

  - AV*, HV* and undef are errors.
  - sv == &PL_sv_yes is a no-op. It is documented as "unfound import,
  ignore".
  - GV*, CV*, code reference are accepted as the source of a CV*.
  - Anything else is presumed to be a string.

Note​: "GV*" is defined as​: SvTYPE(sv) == SVt_PVGV or SvTYPE(sv) == SVt_PVLV
&& isGV_with_GP(sv)

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2013

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2013

From zefram@fysh.org

Eric Brine wrote​:

- sv == &PL_sv_yes is a no-op. It is documented as "unfound import,
ignore".

Freaky​:

$ perl -lwe '1->(); print "OK"'
Undefined subroutine &main​::1 called at -e line 1.
$ perl -lwe '${\!0}->(); print "OK"'
OK

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2013

From @bulk88

On Thu Dec 19 06​:26​:12 2013, ikegami@​adaelis.com wrote​:

A comment in the source says "May be called with any of a CV, a GV, or an
SV containing the name."
.......

But it also accepts a code reference. Specifically, when neither G_METHOD
nor G_METHOD_NAMED was provided as a flag, it takes whatever pp_entersub
takes.

Not testing this.

- AV*, HV* and undef are errors.

HV and undef are tested. AV should be pointless to test.

- sv == &PL_sv_yes is a no-op. It is documented as "unfound import,
ignore".

Tested.

- GV*, CV*, code reference are accepted as the source of a CV*.

Tested.

- Anything else is presumed to be a string.

Tested.

Note​: "GV*" is defined as​: SvTYPE(sv) == SVt_PVGV or SvTYPE(sv) == SVt_PVLV
&& isGV_with_GP(sv)

IDK how to get a LV/isGV_with_GP.

APITest patch attached. Note, some of things being tested are not (and I don't think they should) be public API or documented. If some of the tests are broken in the future, the tests should be fixed or removed, not the future code.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2013

From @bulk88

0001-test-various-types-of-SVs-with-call_sv.patch
From 56fb4c381666bfa4f5db22cfd063056f8433b739 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Sun, 22 Dec 2013 00:45:35 -0500
Subject: [PATCH] test various types of SVs with call_sv

call_sv takes RVs, PVs, CVs, GVs, and an immortal. This isn't well
documented. CVs and immortals can't, or can't easily be tested from
pure perl, so do it from XS. SVt_PVLV with isGV_with_GP is one thing
call_sv takes but is not tested by this commit. Part of [perl #120826] .
---
 ext/XS-APItest/APItest.pm |    2 +-
 ext/XS-APItest/APItest.xs |   77 +++++++++++++++++++++++++++++++++++++++++++++
 ext/XS-APItest/t/call.t   |    9 +++++-
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/ext/XS-APItest/APItest.pm b/ext/XS-APItest/APItest.pm
index 0a07d0e..e454b01 100644
--- a/ext/XS-APItest/APItest.pm
+++ b/ext/XS-APItest/APItest.pm
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 use Carp;
 
-our $VERSION = '0.58';
+our $VERSION = '0.59';
 
 require XSLoader;
 
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index f877047..b2ca380 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -1942,6 +1942,83 @@ mxpushu()
 	mXPUSHu(3);
 	XSRETURN(3);
 
+# indent me todo
+
+void
+call_sv_C()
+PREINIT:
+    CV * i_sub;
+    GV * i_gv;
+    I32 retcnt;
+    SV * errsv;
+    char * errstr;
+    SV * miscsv = sv_newmortal();
+    HV * hv = (HV*)sv_2mortal((SV*)newHV());
+CODE:
+    i_sub = get_cv("i", 0);
+    PUSHMARK(SP);
+    /* PUTBACK not needed since this sub was called with 0 args, and is calling
+      0 args, so global SP doesn't need to be moved before a call_* */
+    retcnt = call_sv((SV*)i_sub, 0); /* try a CV* */
+    SPAGAIN;
+    SP -= retcnt; /* dont care about return count, wipe everything off */
+    sv_setpvs(miscsv, "i");
+    PUSHMARK(SP);
+    retcnt = call_sv(miscsv, 0); /* try a PV */
+    SPAGAIN;
+    SP -= retcnt;
+    /* no add and SVt_NULL are intentional, sub i should be defined already */
+    i_gv = gv_fetchpvn_flags("i", sizeof("i")-1, 0, SVt_NULL);
+    PUSHMARK(SP);
+    retcnt = call_sv((SV*)i_gv, 0); /* try a GV* */
+    SPAGAIN;
+    SP -= retcnt;
+    /* the tests below are not declaring this being public API behavior,
+       only current internal behavior, these tests can be changed in the
+       future if necessery */
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_yes, 0); /* does nothing */
+    SPAGAIN;
+    SP -= retcnt;
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_no, G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Undefined subroutine &main:: called at",
+              sizeof("Undefined subroutine &main:: called at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_undef,  G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Can't use an undefined value as a subroutine reference at",
+              sizeof("Can't use an undefined value as a subroutine reference at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
+    PUSHMARK(SP);
+    retcnt = call_sv((SV*)hv,  G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Not a CODE reference at",
+              sizeof("Not a CODE reference at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
 
 void
 call_sv(sv, flags, ...)
diff --git a/ext/XS-APItest/t/call.t b/ext/XS-APItest/t/call.t
index 7ff9933..54f45ec 100644
--- a/ext/XS-APItest/t/call.t
+++ b/ext/XS-APItest/t/call.t
@@ -11,7 +11,7 @@ use strict;
 
 BEGIN {
     require '../../t/test.pl';
-    plan(436);
+    plan(437);
     use_ok('XS::APItest')
 };
 
@@ -28,6 +28,13 @@ sub f {
     @_, defined wantarray ? wantarray ? 'x' :  'y' : 'z';
 }
 
+our $call_sv_count = 0;
+sub i {
+    $call_sv_count++;
+}
+call_sv_C();
+is($call_sv_count, 6, "call_sv_C passes");
+
 sub d {
     die "its_dead_jim\n";
 }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2013

From @bulk88

On Sat Dec 21 21​:53​:42 2013, bulk88 wrote​:

APITest patch attached. Note, some of things being tested are not (and
I don't think they should) be public API or documented. If some of the
tests are broken in the future, the tests should be fixed or removed,
not the future code.

Stray leftover comment was in the last patch, new patch attached.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2013

From @bulk88

0001-test-various-types-of-SVs-with-call_sv.patch
From f98fa5e1bf43e0fe8fd05a38a40ff9ce4da5c2fa Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Sun, 22 Dec 2013 00:54:14 -0500
Subject: [PATCH] test various types of SVs with call_sv

call_sv takes RVs, PVs, CVs, GVs, and an immortal. This isn't well
documented. CVs and immortals can't, or can't easily be tested from
pure perl, so do it from XS. SVt_PVLV with isGV_with_GP is one thing
call_sv takes but is not tested by this commit. Part of [perl #120826] .
---
 ext/XS-APItest/APItest.pm |    2 +-
 ext/XS-APItest/APItest.xs |   75 +++++++++++++++++++++++++++++++++++++++++++++
 ext/XS-APItest/t/call.t   |    9 +++++-
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/ext/XS-APItest/APItest.pm b/ext/XS-APItest/APItest.pm
index 0a07d0e..e454b01 100644
--- a/ext/XS-APItest/APItest.pm
+++ b/ext/XS-APItest/APItest.pm
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 use Carp;
 
-our $VERSION = '0.58';
+our $VERSION = '0.59';
 
 require XSLoader;
 
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index f877047..e352195 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -1942,6 +1942,81 @@ mxpushu()
 	mXPUSHu(3);
 	XSRETURN(3);
 
+void
+call_sv_C()
+PREINIT:
+    CV * i_sub;
+    GV * i_gv;
+    I32 retcnt;
+    SV * errsv;
+    char * errstr;
+    SV * miscsv = sv_newmortal();
+    HV * hv = (HV*)sv_2mortal((SV*)newHV());
+CODE:
+    i_sub = get_cv("i", 0);
+    PUSHMARK(SP);
+    /* PUTBACK not needed since this sub was called with 0 args, and is calling
+      0 args, so global SP doesn't need to be moved before a call_* */
+    retcnt = call_sv((SV*)i_sub, 0); /* try a CV* */
+    SPAGAIN;
+    SP -= retcnt; /* dont care about return count, wipe everything off */
+    sv_setpvs(miscsv, "i");
+    PUSHMARK(SP);
+    retcnt = call_sv(miscsv, 0); /* try a PV */
+    SPAGAIN;
+    SP -= retcnt;
+    /* no add and SVt_NULL are intentional, sub i should be defined already */
+    i_gv = gv_fetchpvn_flags("i", sizeof("i")-1, 0, SVt_NULL);
+    PUSHMARK(SP);
+    retcnt = call_sv((SV*)i_gv, 0); /* try a GV* */
+    SPAGAIN;
+    SP -= retcnt;
+    /* the tests below are not declaring this being public API behavior,
+       only current internal behavior, these tests can be changed in the
+       future if necessery */
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_yes, 0); /* does nothing */
+    SPAGAIN;
+    SP -= retcnt;
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_no, G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Undefined subroutine &main:: called at",
+              sizeof("Undefined subroutine &main:: called at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
+    PUSHMARK(SP);
+    retcnt = call_sv(&PL_sv_undef,  G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Can't use an undefined value as a subroutine reference at",
+              sizeof("Can't use an undefined value as a subroutine reference at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
+    PUSHMARK(SP);
+    retcnt = call_sv((SV*)hv,  G_EVAL);
+    SPAGAIN;
+    SP -= retcnt;
+    errsv = ERRSV;
+    errstr = SvPV_nolen(errsv);
+    if(strnEQ(errstr, "Not a CODE reference at",
+              sizeof("Not a CODE reference at") - 1)) {
+        PUSHMARK(SP);
+        retcnt = call_sv((SV*)i_sub, 0); /* call again to increase counter */
+        SPAGAIN;
+        SP -= retcnt;
+    }
 
 void
 call_sv(sv, flags, ...)
diff --git a/ext/XS-APItest/t/call.t b/ext/XS-APItest/t/call.t
index 7ff9933..54f45ec 100644
--- a/ext/XS-APItest/t/call.t
+++ b/ext/XS-APItest/t/call.t
@@ -11,7 +11,7 @@ use strict;
 
 BEGIN {
     require '../../t/test.pl';
-    plan(436);
+    plan(437);
     use_ok('XS::APItest')
 };
 
@@ -28,6 +28,13 @@ sub f {
     @_, defined wantarray ? wantarray ? 'x' :  'y' : 'z';
 }
 
+our $call_sv_count = 0;
+sub i {
+    $call_sv_count++;
+}
+call_sv_C();
+is($call_sv_count, 6, "call_sv_C passes");
+
 sub d {
     die "its_dead_jim\n";
 }
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2013

From perl5-porters@perl.org

bulk88 wrote​:

IDK how to get a LV/isGV_with_GP.

Return a glob from a tied array element.
Or assign one to a nonexistent element via a sub​:

sub {
  $_[0] = *foo;
  # $_[0] is now a pavlov glob
}->($h{doesnotexist})

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 2013

From @bulk88

On Sat Dec 21 21​:56​:28 2013, bulk88 wrote​:

Stray leftover comment was in the last patch, new patch attached.

this got a commit by FC but no confirmation post in this ticket, this bug is to stay open since the commit didnt fix the docs for call_sv

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Dec 24, 2013

From perl5-porters@perl.org

Daniel Dragan wrote​:

this got a commit by FC but no confirmation post in this ticket, this bug is to
stay open since the commit didnt fix the docs for call_sv

Sorry, I ran out of time when I was about to say so.

The commit id was a85ce6f.

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2015

From @tonycoz

On Mon Dec 23 13​:40​:49 2013, bulk88 wrote​:

On Sat Dec 21 21​:56​:28 2013, bulk88 wrote​:

Stray leftover comment was in the last patch, new patch attached.

this got a commit by FC but no confirmation post in this ticket, this
bug is to stay open since the commit didnt fix the docs for call_sv

Patch for the docs attached.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2015

From @tonycoz

0001-perl-120826-correct-documentation-of-sv-parameter-of.patch
From 134f355583aaad80e6de89bd5e975d5fe22ba481 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 9 Jul 2015 11:49:31 +1000
Subject: [PATCH] [perl #120826] correct documentation of sv parameter of
 call_sv()

---
 perl.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/perl.c b/perl.c
index cbb66e0..fad0cbf 100644
--- a/perl.c
+++ b/perl.c
@@ -2664,8 +2664,22 @@ Perl_call_method(pTHX_ const char *methname, I32 flags)
 /*
 =for apidoc p||call_sv
 
-Performs a callback to the Perl sub whose name is in the SV.  See
-L<perlcall>.
+Performs a callback to the Perl sub specified by the SV.
+
+If neither the G_METHOD or G_METHOD_NAMED flag is supplied, the SV may
+be any of a CV, a GV, a reference to a CV, a reference to a GV or the
+name of the sub to call.
+
+If the G_METHOD flag is supplied, the SV may be a refernce to a CV of
+the name of the method to call.
+
+If the G_METHOD_NAMED flag is supplied, the SV must be the name of the
+method.
+
+Some other values are treated specially for internal use and should
+not be depended on.
+
+See L<perlcall>.
 
 =cut
 */
-- 
1.7.10.4

@p5pRT
Copy link
Author

p5pRT commented Jul 9, 2015

From @bulk88

On Wed Jul 08 18​:55​:41 2015, tonyc wrote​:

On Mon Dec 23 13​:40​:49 2013, bulk88 wrote​:

On Sat Dec 21 21​:56​:28 2013, bulk88 wrote​:

Stray leftover comment was in the last patch, new patch attached.

this got a commit by FC but no confirmation post in this ticket, this
bug is to stay open since the commit didnt fix the docs for call_sv

Patch for the docs attached.

Tony

No objections.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @bulk88

On Wed Jul 08 20​:39​:54 2015, bulk88 wrote​:

On Wed Jul 08 18​:55​:41 2015, tonyc wrote​:

On Mon Dec 23 13​:40​:49 2013, bulk88 wrote​:

On Sat Dec 21 21​:56​:28 2013, bulk88 wrote​:

Stray leftover comment was in the last patch, new patch attached.

this got a commit by FC but no confirmation post in this ticket, this
bug is to stay open since the commit didnt fix the docs for call_sv

Patch for the docs attached.

Tony

No objections.

Okay, maybe I have some objections.

+Performs a callback to the Perl sub specified by the SV.
+
+If neither the G_METHOD or G_METHOD_NAMED flag is supplied, the SV may
+be any of a CV, a GV, a reference to a CV, a reference to a GV or the
+name of the sub to call.

"the SVPV name of the sub to call", name is not a technical term, it isn't obvious what a name is in Perl API. Instead of SVPV, "PV" is okay too.

+If the G_METHOD flag is supplied, the SV may be a refernce to a CV of
+the name of the method to call.

"name" is ambiguous, see above.

+If the G_METHOD_NAMED flag is supplied, the SV must be the name of the
+method.

"name" is ambiguous, see above.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @tonycoz

On Sun Aug 02 21​:54​:28 2015, bulk88 wrote​:

On Wed Jul 08 20​:39​:54 2015, bulk88 wrote​:

No objections.

Okay, maybe I have some objections.

+Performs a callback to the Perl sub specified by the SV.
+
+If neither the G_METHOD or G_METHOD_NAMED flag is supplied, the SV
may
+be any of a CV, a GV, a reference to a CV, a reference to a GV or the
+name of the sub to call.

"the SVPV name of the sub to call", name is not a technical term, it
isn't obvious what a name is in Perl API. Instead of SVPV, "PV" is
okay too.

+If the G_METHOD flag is supplied, the SV may be a refernce to a CV of
+the name of the method to call.

"name" is ambiguous, see above.

+If the G_METHOD_NAMED flag is supplied, the SV must be the name of
the
+method.

"name" is ambiguous, see above.

Updated patch attached.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @tonycoz

0001-perl-120826-correct-documentation-of-sv-parameter-of.patch
From a91d260a0ab22a37a1706f0b8cb6369705a5d175 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 3 Aug 2015 16:48:01 +1000
Subject: [PATCH] [perl #120826] correct documentation of sv parameter of
 call_sv()

---
 perl.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/perl.c b/perl.c
index 1af5e29..1823c99 100644
--- a/perl.c
+++ b/perl.c
@@ -2664,8 +2664,22 @@ Perl_call_method(pTHX_ const char *methname, I32 flags)
 /*
 =for apidoc p||call_sv
 
-Performs a callback to the Perl sub whose name is in the SV.  See
-L<perlcall>.
+Performs a callback to the Perl sub specified by the SV.
+
+If neither the C<G_METHOD> or C<G_METHOD_NAMED> flag is supplied, the
+SV may be any of a CV, a GV, a reference to a CV, a reference to a GV
+or C<SvPV(sv)> will be used as the name of the sub to call.
+
+If the C<G_METHOD> flag is supplied, the SV may be a reference to a CV or
+C<SvPV(sv)> will be used as the name of the method to call.
+
+If the C<G_METHOD_NAMED> flag is supplied, C<SvPV(sv)> will be used as
+the name of the method to call.
+
+Some other values are treated specially for internal use and should
+not be depended on.
+
+See L<perlcall>.
 
 =cut
 */
-- 
1.7.10.4

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @bulk88

On Sun Aug 02 23​:49​:25 2015, tonyc wrote​:

Updated patch attached.

Tony

New version is okay. Once this patch is applied, this 1 yr 7 mo old ticket can finally be closed.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Aug 5, 2015

From @tonycoz

On Mon Aug 03 04​:04​:09 2015, bulk88 wrote​:

On Sun Aug 02 23​:49​:25 2015, tonyc wrote​:

Updated patch attached.

Tony

New version is okay. Once this patch is applied, this 1 yr 7 mo old
ticket can finally be closed.

Applied as 078e221.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 5, 2015

@tonycoz - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Aug 5, 2015
@p5pRT
Copy link
Author

p5pRT commented Aug 5, 2015

From @ikegami

That text contains "neither..or" instead of "neither..nor".

If neither the C<G_METHOD> or C<G_METHOD_NAMED> flag is supplied

should be

If neither the C<G_METHOD> flag nor the C<G_METHOD_NAMED> flag is supplied

or

If neither of the C<G_METHOD> and C<G_METHOD_NAMED> flags are supplied

On Wed, Aug 5, 2015 at 12​:57 AM, Tony Cook via RT <perlbug-followup@​perl.org

wrote​:

On Mon Aug 03 04​:04​:09 2015, bulk88 wrote​:

On Sun Aug 02 23​:49​:25 2015, tonyc wrote​:

Updated patch attached.

Tony

New version is okay. Once this patch is applied, this 1 yr 7 mo old
ticket can finally be closed.

Applied as 078e221.

Tony

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=120826

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2015

From @wolfsage

On Wed, Aug 5, 2015 at 3​:22 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

That text contains "neither..or" instead of "neither..nor".

If neither the C<G_METHOD> or C<G_METHOD_NAMED> flag is supplied

should be

If neither the C<G_METHOD> flag nor the C<G_METHOD_NAMED> flag is supplied

Fixed in 7c0c544.

Thanks.

-- Matthew Horsfall (alh)

@p5pRT p5pRT added the hasPatch label Oct 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant