elderon mini sample

Verfasst von

in

=== mailverkehr

Re: long external PL/I names
From Peter ElderonAdd contact
To johann woeckingerAdd contact
Date 2015-05-21 20:58
Message 4 of 10 < >
johann.job
Hello Johann,

the attached job is my version of what you were attempting. Note that I made the methods in the function table LIMITED ENTRY and that in their compilation unit that they are all level-1 procedures in the package

if this version is to be reentrant, all the code should be compiled with the RENT option

– Peter
From: johann woeckinger <johann@woeckinger.at>
To: Peter Elderon/Santa Teresa/IBM@IBMUS
Date: 05/20/2015 12:29 PM
Subject: Re: long external PL/I names
Sent by: woecki@gmail.com

hi peter,

thanks for your reply. just to make sure that my question was not unclear i try to provide a broken-down-to-the-minimum example of my experiment:
i implement a „math“ class with several methods (set, add, get).
the external entry returns some entry variables (the „method table“) which are called afterwards.
everything is ok until i call another fetchable from one of the „methods“.

i would assume that calling the internal functions in the math-fetchable via entry var and calling the fetchable woe09f0 afterwards breaks the stack frame (or something similar). or am i missing something else? should this really work?

br johann

ps: did some research and found https://groups.google.com/forum/#!searchin/comp.lang.pl1/entry$20pointer/comp.lang.pl1/kKQv0yZyrcY/32Tt_r9yfG0J which imho is about a similar question, if i read it correctly the posters came to the conclusion that it doesn’t work.
== include, the „math“ class
dcl 1 p_math ptr; /* might be more elegant via defined type & handle, but for simplicity i use ptr + struct */
dcl 1 c_math based(p_math),
2 data,
3 sum dec fixed(13,2),
2 ft,
3 set entry(ptr, dec fixed(13,2)),
3 add entry(ptr, dec fixed(13,2)),
3 get entry(ptr) returns(dec fixed(13,2));

== implementation of „math“
woe09g0: proc() returns(ptr) options(fetchable);
%xinclude woe09g01;
dcl woe09f0 external entry(char) options(fetchable); /* just to trigger the error, might be some tracing etc… */

p_math = alloc(size(C_math)); /* „constructor“ */
c_math.data.sum = 0;
c_math.set = set; /* init the „method table“ */
c_math.get = get;
c_math.add = add;

return(p_math);

set: proc(this, val); /* various „methods“ */
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);
obj.sum = val;
end set;

add: proc(this, val);
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);
obj.sum += val;
call woe09f0(“a”); <<< as soon as i add this, i get an ONCODE=8091 Operation exception <<<
end add;

get: proc(this) returns(dec fixed(13,2));
dcl this ptr; dcl obj like C_math based(this);
return(obj.sum);
end get;

end woe09g0;

== usage
funcptr:proc();

%xinclude woe09g01; /* „class“ math */
dcl woe09g0 entry() returns(ptr) options(fetchable); /* the „math“ „constructor“ */
dcl o1_ ptr; dcl o1 like c_math based(o1_);

o1_ = woe09g0(); /* „instantiate“ math */

call o1.set(o1_, 0);

call o1.add(o1_, 3);
call o1.add(o1_, 14);

dcl x dec fixed(13,2);
x = o1.get(o1_);

end funcptr;

== woe09f0, fetchable that causes exception,
woe09f0: proc(par)
options(fetchable);

dcl par char(15);
if par <> ”
then
par = trim(par)!!’.‘; /* just some uncritical(?) operations */

end woe09f0;

On 11 May 2015 at 18:07, Peter Elderon <elderon@us.ibm.com> wrote:
Hello Johann,

to do fetch from inside a fetched routine, you must use the RENT compiler option

– Peter
From: johann woeckinger <johann@woeckinger.at>
To: Peter Elderon/Santa Teresa/IBM@IBMUS
Date: 05/10/2015 11:21 PM
Subject: Re: long external PL/I names
Sent by: woecki@gmail.com

Hello Peter!
Sorry for bothering you again (just let me know if you wana stop this informal chit-chat with me), but i have a follow-up question regarding the calling of functions in fetchables via Entry pointers: i am able to implement calling a local Funktion oft a fetchable via an Entry pointer, but as soon as this Funktion calls another fetchable, i get a protection exception. Should this work ? Anything special to care about?
Thanks in advance,
BR johann
Am 24.04.2015 07:53 schrieb „johann woeckinger“ <woecki@gmail.com>:
Hi Peter,
Ok, then i feel less stomachache when i meet such code :-),
thanks, br Johann

On 23 April 2015 at 02:05, Peter Elderon <elderon@us.ibm.com> wrote:
Hi Johann,

the code you describe would be perfectly ok. In fact, with some modifications it could be used to create object-oriented code (the part of the structure containing the entry variables is what would often be called a „method table“)

but this doesn’t violate anything in LE or PL/I, and we have some code very similar to this in the compiler itself (and the compiler is written in PL/I)

– Peter
From: johann woeckinger <woecki@gmail.com>
To: Peter Elderon/Santa Teresa/IBM@IBMUS
Date: 04/22/2015 01:18 PM
Subject: Re: long external PL/I names

Hi Peter!

Thanks for he quick and clear answer!
Your suggestion sounds great, i have to give it a try once i get around some internal limits. We have some (tool enforced) coding rules that prevent me from building the „package export(long_name ext(…“ code.

May i ask you one more question which is somehow related to the implementation of multi-entry fetchables? I’ve seen code where one implements a fetchable proc that contains some internal functions. When the fetchable entry is called it allocates a struct that contains some „entry“ variables, assigns the internal functions to the entries and returns the struct. The caller can now call the internal functions of the fetchable by calling the entry-variables from the struct it just got from the fetchable!
Wow, that looks dangerous to me, but it seems to work. I assume this is not recommended as it circumvents (at least) some LE concepts, but are there any additional comments from your side?

thanks again & br
Johann

PS: Just for the records: I’m a colleague of Gerhard Aistleitner From Racon/GRZ Linz, Austria, i think you’ve been in contact with him. My postings in comp.lang.pl1 and ibm-dw-pli-cafe are not aligned with him, i’m just interested in learning more about pl/i.
?

 

 

== include
dcl 1 p_math ptr;
dcl 1 c_math based(p_math),
2 data,
3 sum dec fixed(13,2),
2 ft,
3 set entry(ptr, dec fixed(13,2)),
3 add entry(ptr, dec fixed(13,2)),
3 get entry(ptr) returns(dec fixed(13,2));

== implementation
woe09g0: proc() returns(ptr) options(fetchable);
%xinclude woe09g01;
dcl woe09f0 external entry(char) options(fetchable);

p_math = alloc(size(C_math));
c_math.data.sum = 0;
c_math.set = set;
c_math.get = get;
c_math.add = add;

return(p_math);

set: proc(this, val);
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);
obj.sum = val;
end set;

add: proc(this, val);
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);
obj.sum += val;
call woe09f0(„a“); <<< as soon as i add this, i get an ONCODE=8091 Operation exception
end add;

get: proc(this) returns(dec fixed(13,2));
dcl this ptr; dcl obj like C_math based(this);
return(obj.sum);
end get;

end woe09g0;

== usage
funcptr:proc();

%xinclude woe09g01;
dcl woe09g0 entry() returns(ptr) options(fetchable);
dcl woe09f0 external entry(char) options(fetchable);

dcl o1_ ptr; dcl o1 like c_math based(o1_);

o1_ = woe09g0();

call o1.set(o1_, 0);

call o1.add(o1_, 3);
call o1.add(o1_, 14);

dcl x dec fixed(13,2);
x = o1.get(o1_);

end funcptr;

== woe09f0, fetchable that causes exception
woe09f0: proc(par)
options(fetchable);

dcl par char(15);
if par <> “
then
par = trim(par)!!‘.‘;

end woe09f0;

 

 

—-johann.job

//*
//*
//*********************************************************************
//* compile first fetchable procedure
//*********************************************************************
//PLI1 EXEC PGM=IBMZPLI,PARM=’OP‘
//STEPLIB DD DSN=ENPLI440.SIBMZCMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLIN DD DSN=&&LOADSET1,DISP=(MOD,PASS),UNIT=SYSSQ,
// SPACE=(CYL,(3,1))
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,
// SPACE=(1024,(200,50),,CONTIG,ROUND),DCB=BLKSIZE=1024
//SYSLIB DD DISP=SHR,DSN=ELDERON.PORT.INCLUDES
//SYSIN DD *
*process display(std) s;
math: package exports( woe09g0 );

%xinclude woe09g01;

/* just to trigger the error, might be some tracing etc… */
dcl woe09f0 external entry(fixed bin(31) ) options(fetchable);

woe09g0: proc() returns(ptr) options(fetchable);

p_math = alloc(size(C_math));
c_math.data.sum = 0;
c_math.set = set;
c_math.get = get;
c_math.add = add;

return(p_math);
end;

set: proc(this, val); /* various „methods“ */
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);

obj.sum = val;
end set;

add: proc(this, val);
dcl this ptr; dcl obj like c_math based(this);
dcl val dec fixed(13,2);

display( procname() || sourceline() );
obj.sum += val;
call woe09f0( 1729 );
display( procname() || sourceline() );
end add;

get: proc(this) returns(dec fixed(13,2));
dcl this ptr; dcl obj like C_math based(this);

return(obj.sum);
end get;

//*********************************************************************
//* link
//*********************************************************************
//LKED1 EXEC PGM=IEWL,PARM=’XREF,LIST,LET‘,
// COND=(9,LT),REGION=5000K
//SYSLIB DD DSN=CEEV2R1Z.SCEELKED,DISP=SHR
//SYSLMOD DD DSN=&&FETSET1(WOE09G0),DISP=(NEW,PASS),UNIT=SYSDA,
// SPACE=(TRK,(7,1,1)),DSNTYPE=LIBRARY
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(CYL,(3,1)),
// DCB=BLKSIZE=1024
//SYSPRINT DD SYSOUT=*
//SYSDEFSD DD DUMMY
//SYSLIN DD DSN=&&LOADSET1,DISP=SHR
// DD DDNAME=SYSIN
//LKED1.SYSIN DD *
ENTRY WOE09G0
//* ENTRY CEESTART
//*
//*
//*
//*********************************************************************
//* compile second fetchable procedure
//*********************************************************************
//PLI2 EXEC PGM=IBMZPLI
//STEPLIB DD DSN=ENPLI440.SIBMZCMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLIN DD DSN=&&LOADSET2,DISP=(MOD,PASS),UNIT=SYSSQ,
// SPACE=(CYL,(3,1))
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,
// SPACE=(1024,(200,50),,CONTIG,ROUND),DCB=BLKSIZE=1024
//SYSLIB DD DISP=SHR,DSN=ELDERON.PORT.INCLUDES
//SYSIN DD *
*process display(std) s;

woe09f0: proc( parm ) options(fetchable);

dcl parm fixed bin(31);

display( procname() || sourceline() );
display( parm );
end;

//*********************************************************************
//* link
//*********************************************************************
//LKED2 EXEC PGM=IEWL,PARM=’XREF,LIST,LET‘,
// COND=(9,LT),REGION=5000K
//SYSLIB DD DSN=CEEV2R1Z.SCEELKED,DISP=SHR
//SYSLMOD DD DSN=&&FETSET2(WOE09F0),DISP=(NEW,PASS),UNIT=SYSDA,
// SPACE=(TRK,(7,1,1)),DSNTYPE=LIBRARY
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(CYL,(3,1)),
// DCB=BLKSIZE=1024
//SYSPRINT DD SYSOUT=*
//SYSDEFSD DD DUMMY
//SYSLIN DD DSN=&&LOADSET2,DISP=SHR
// DD DDNAME=SYSIN
//LKED2.SYSIN DD *
ENTRY WOE09F0
//* ENTRY CEESTART
//*
//*
//*
//*
//*********************************************************************
//* compile main procedure
//*********************************************************************
//PLI EXEC PGM=IBMZPLI
//STEPLIB DD DSN=ENPLI440.SIBMZCMP,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSSQ,
// SPACE=(CYL,(3,1))
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,
// SPACE=(1024,(200,50),,CONTIG,ROUND),DCB=BLKSIZE=1024
//SYSLIB DD DISP=SHR,DSN=ELDERON.PORT.INCLUDES
//SYSIN DD *
*process display(std) s;
main:proc options(main);

%xinclude woe09g01;

dcl woe09g0 entry()
returns( pointer byvalue )
options(fetchable);

dcl o1_ ptr; dcl o1 like c_math based(o1_);

dcl x dec fixed(13,2);

display( procname() || sourceline() );

o1_ = woe09g0(); /* „instantiate“ math */

display( procname() || sourceline() );

call o1.set(o1_, 0);

call o1.add(o1_, 3);
call o1.add(o1_, 14);

display( procname() || sourceline() );

x = o1.get(o1_);

display( procname() || sourceline() );
display( x );

end;
//**
//*********************************************************************
//* LINK STEP
//*********************************************************************
//LKED EXEC PGM=IEWL,PARM=’XREF,LIST,LET‘,
// COND=(7,LT),REGION=5000K
//SYSLIB DD DSN=CEEV2R1Z.SCEELKED,DISP=SHR
//SYSLMOD DD DSN=&&GOSET(GO),DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(CYL,(1,1,1)),DSNTYPE=LIBRARY
//SYSUT1 DD DSN=&&SYSUT1,UNIT=SYSDA,SPACE=(CYL,(3,1)),
// DCB=BLKSIZE=1024
//SYSPRINT DD DUMMY
//SYSLIN DD DSN=&&LOADSET,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
//LKED.SYSIN DD *
ENTRY CEESTART
//**
//GO EXEC PGM=*.LKED.SYSLMOD,COND=(7,LT)
//STEPLIB DD DSN=&&FETSET1,DISP=SHR
// DD DSN=&&FETSET2,DISP=SHR
// DD DSN=CEEV2R1Z.SCEERUN,DISP=SHR
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=X
//