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

OP_ENTERSUB is not called for constructor of tied object #16382

Closed
p5pRT opened this issue Jan 25, 2018 · 7 comments
Closed

OP_ENTERSUB is not called for constructor of tied object #16382

p5pRT opened this issue Jan 25, 2018 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 25, 2018

Migrated from rt.perl.org#132768 (status was 'rejected')

Searchable as RT132768$

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2018

From @KES777

Created by @KES777

TLDR;
When we tie scalar to 'MyObj' class the MyObj​::TIESCALAR is called
but OP_ENTERSUB is not executed before that.
But still we can see OP_LEAVESUB for it

How to reproduce​:
$cat script.pl
package Obj;
sub DESTROY {
  print "DESTROY\n";
}

sub new{ bless {} };
package MyTie;

our $test;

sub TIESCALAR {
  bless {}, 'MyTie​::Scalar';
}

package MyTie​::Scalar;

package main;

sub MyTie​::Scalar​::FETCH {
  local $MyTie​::test = Obj->new;
  print "FETCHed\n";
  return 7;
}

my $x;
tie $x, 'MyTie';
{
  local $MyTie​::test = 3;
  print $x;

  print "TEST​: $MyTie​::test\n";
}

$cat script.xs
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

int
My_runops2(pTHX){
  SV* id = get_sv("DB​::runops_id", GV_ADD|GV_ADDMULTI);
  save_item( id );
  sv_inc_nomg( id );
  int idv = SvIV( id );

  printf( "Run OP start(%d)\n", idv );

  SV *tv = newSVpvs( "MyTie​::Scalar" );

  OP *o; CV *cv; SV *pkg;
  while( PL_op ) {
  o = PL_op;

  SV* intv = get_sv("DB​::intv", 0);
  printf( "OP Type​: %d -- %s intv​:%d\n", o->op_type, OP_DESC( o ), SvTRUE( intv ) );

  switch( o->op_type ) {
  case OP_ENTERSUB​:;
  PL_op = o = CALL_FPTR(o->op_ppaddr)(aTHX);

  cv = find_runcv(0);
  pkg = newSVpv( HvNAME( GvSTASH(CvGV(cv)) ), 0 );
  printf( "ENTER​: %s​::%s\n", SvPV_nolen( pkg ), GvNAME( CvGV(cv) ) );

  // sv_dump( cv );
  break;
  case OP_LEAVESUB​:;

  cv = find_runcv(0);
  pkg = newSVpv( HvNAME( GvSTASH(CvGV(cv)) ), 0 );
  printf( "LEAVE​: %s​::%s\n", SvPV_nolen( pkg ), GvNAME( CvGV(cv) ) );

  // sv_dump( cv );
  break;
  }

  PL_op = CALL_FPTR(o->op_ppaddr)(aTHX);
  }

  printf( "Run OP finish (%d)\n", idv );

  PERL_ASYNC_CHECK();
  TAINT_NOT;
  return 0;
}

MODULE = Module PACKAGE = Module
BOOT​:
  get_sv("DB​::intv", GV_ADD|GV_ADDMULTI);

  PL_runops = My_runops2;

$perl -MModule script.pl
Run OP start(1)
OP Type​: 0 -- null operation intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 68 -- string intv​:0
Run OP finish (1)
Run OP start(1)
OP Type​: 0 -- null operation intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 68 -- string intv​:0
Run OP finish (1)
Run OP start(1)
OP Type​: 196 -- block entry intv​:0
OP Type​: 193 -- next statement intv​:0
OP Type​: 9 -- private variable intv​:0
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 9 -- private variable intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 226 -- tie intv​:0

/*** here TIESCALAR is called but there is no OP_ENTERSUB for it ***/
Run OP start(2)
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 161 -- anonymous hash ({}) intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 23 -- bless intv​:0
OP Type​: 186 -- subroutine exit intv​:0
LEAVE​: MyTie​::TIESCALAR
Run OP finish (2)

/*** Actually next is not relevant, but provided for completeness ***/

OP Type​: 193 -- next statement intv​:0
OP Type​: 201 -- loop entry intv​:0
OP Type​: 193 -- next statement intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 6 -- scalar variable intv​:0
OP Type​: 37 -- scalar assignment intv​:0
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 9 -- private variable intv​:0
OP Type​: 238 -- print intv​:0
Run OP start(2)
OP Type​: 210 -- method with known name intv​:0
OP Type​: 185 -- subroutine entry intv​:0
ENTER​: MyTie​::Scalar​::FETCH
OP Type​: 3 -- pushmark intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 210 -- method with known name intv​:0
OP Type​: 185 -- subroutine entry intv​:0
ENTER​: Obj​::new
OP Type​: 3 -- pushmark intv​:0
OP Type​: 161 -- anonymous hash ({}) intv​:0
OP Type​: 23 -- bless intv​:0
OP Type​: 186 -- subroutine exit intv​:0
LEAVE​: Obj​::new
OP Type​: 6 -- scalar variable intv​:0
OP Type​: 37 -- scalar assignment intv​:0
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 238 -- print intv​:0
FETCHed
OP Type​: 193 -- next statement intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 186 -- subroutine exit intv​:0
LEAVE​: MyTie​::Scalar​::FETCH
Run OP start(3)
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 238 -- print intv​:0
DESTROY
OP Type​: 186 -- subroutine exit intv​:0
LEAVE​: Obj​::DESTROY
Run OP finish (3)
Run OP finish (2)
OP Type​: 193 -- next statement intv​:0
OP Type​: 3 -- pushmark intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 6 -- scalar variable intv​:0
OP Type​: 67 -- concatenation (.) or string intv​:0
OP Type​: 5 -- constant item intv​:0
OP Type​: 67 -- concatenation (.) or string intv​:0
OP Type​: 238 -- print intv​:0
7TEST​: 3
OP Type​: 202 -- loop exit intv​:0
OP Type​: 197 -- block exit intv​:0
Run OP finish (1)

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.24.0:

Configured by kes at Wed Oct 19 14:07:47 EEST 2016.

Summary of my perl5 (revision 5 version 24 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=4.4.0-43-generic, archname=x86_64-linux
    uname='linux work 4.4.0-43-generic #63-ubuntu smp wed oct 12 13:48:03 utc 2016 x86_64 x86_64 x86_64 gnulinux '
    config_args='-de -Dprefix=/home/kes/perl5/perlbrew/perls/perl-5.24.0 -Aeval:scriptdir=/home/kes/perl5/perlbrew/perls/perl-5.24.0/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion='', gccversion='5.4.0 20160609', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /lib64 /usr/lib64
    libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.23.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.23'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

Locally applied patches:
    Devel::PatchPerl 1.38


@INC for perl 5.24.0:
    /home/kes/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/x86_64-linux
    /home/kes/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0
    /home/kes/perl5/perlbrew/perls/perl-5.24.0/lib/5.24.0/x86_64-linux
    /home/kes/perl5/perlbrew/perls/perl-5.24.0/lib/5.24.0
    .


Environment for perl 5.24.0:
    HOME=/home/kes
    LANG=en_US.UTF-8
    LANGUAGE=en
    LC_ADDRESS=uk_UA.UTF-8
    LC_IDENTIFICATION=uk_UA.UTF-8
    LC_MEASUREMENT=uk_UA.UTF-8
    LC_MESSAGES=en_US.UTF-8
    LC_MONETARY=uk_UA.UTF-8
    LC_NAME=uk_UA.UTF-8
    LC_NUMERIC=uk_UA.UTF-8
    LC_PAPER=uk_UA.UTF-8
    LC_TELEPHONE=uk_UA.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/kes/perl5/perlbrew/bin:/home/kes/perl5/perlbrew/perls/perl-5.24.0/bin:/home/kes/bin:/home/kes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
    PERLBREW=command perlbrew
    PERLBREW_BASHRC_VERSION=0.78
    PERLBREW_HOME=/home/kes/.perlbrew
    PERLBREW_MANPATH=/home/kes/perl5/perlbrew/perls/perl-5.24.0/man
    PERLBREW_PATH=/home/kes/perl5/perlbrew/bin:/home/kes/perl5/perlbrew/perls/perl-5.24.0/bin
    PERLBREW_PERL=perl-5.24.0
    PERLBREW_ROOT=/home/kes/perl5/perlbrew
    PERLBREW_VERSION=0.78
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2018

From @iabyn

On Thu, Jan 25, 2018 at 10​:00​:29AM -0800, KES wrote​:

When we tie scalar to 'MyObj' class the MyObj​::TIESCALAR is called
but OP_ENTERSUB is not executed before that.
But still we can see OP_LEAVESUB for it

pp_entersub() is still called, but it is called directly, rather than from
a runops loop. Is this a problem for you?

--
In economics, the exam questions are the same every year.
They just change the answers.

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2018

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

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2018

From @KES777

yes, it is. Because when I count depth level it occasionally became negative.
So it is better to see both corresponding events.

Also I have noticed that for the DESTROY method pp_entersub is not called from a runops loop too.

@p5pRT
Copy link
Author

p5pRT commented Jan 28, 2018

From zefram@fysh.org

KES wrote​:

When we tie scalar to 'MyObj' class the MyObj​::TIESCALAR is called
but OP_ENTERSUB is not executed before that.

Not a bug. There is no entersub op because the sub call is not being
made from Perl code. There are many places in which subs get called by
means other than explicit calls from Perl code. Any XS code can make
a sub call, and we even have a whole documentation file advising XS
programmers how to do that. It is not remotely viable to rely on sub
calls being made only through Perl ops.

But still we can see OP_LEAVESUB for it

The leavesub op isn't part of the call site, it's part of the called sub.
Of course it only exists for a called Perl sub. You'll see the opposite
pattern when calling an XS sub explicitly from Perl code​: an entersub
op at the call site, then no leavesub or any other op until control has
returned to the call site and moved on to the next thing.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Feb 12, 2018

From @iabyn

On Sun, Jan 28, 2018 at 01​:03​:57PM +0000, Zefram wrote​:

KES wrote​:

When we tie scalar to 'MyObj' class the MyObj​::TIESCALAR is called
but OP_ENTERSUB is not executed before that.

Not a bug. There is no entersub op because the sub call is not being
made from Perl code. There are many places in which subs get called by
means other than explicit calls from Perl code. Any XS code can make
a sub call, and we even have a whole documentation file advising XS
programmers how to do that. It is not remotely viable to rely on sub
calls being made only through Perl ops.

But still we can see OP_LEAVESUB for it

The leavesub op isn't part of the call site, it's part of the called sub.
Of course it only exists for a called Perl sub. You'll see the opposite
pattern when calling an XS sub explicitly from Perl code​: an entersub
op at the call site, then no leavesub or any other op until control has
returned to the call site and moved on to the next thing.

I agree that this ticket should be rejected.

--
"I do not resent criticism, even when, for the sake of emphasis,
it parts for the time with reality".
  -- Winston Churchill, House of Commons, 22nd Jan 1941.

@p5pRT
Copy link
Author

p5pRT commented Feb 12, 2018

@xsawyerx - Status changed from 'open' to 'rejected'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant