Title: Subprogram and its implementation
1Subprogram and its implementation
2Fundamentals
- Two fundamental abstractions in PL
- Process abstraction (subprogram)
- Data abstraction (chap 11)
- Subprogram characteristics
- Single entry point
- Caller is suspended during callee execution
- Control returns to caller when callee execution
terminates
3Definitions
- Subprogram definition describes the interface to
and the actions of the subprogram abstraction - Header 1st part of the definition (name, return
type, parameters) - Parameter profile describes the number, order
and type of its formal parameters - Declaration providing type information
4Parameters
- Two ways for subprogram to gain access to the
data it is to process - Direct access to nonlocal variables
- Parameter passing
5Parameters (cont.)
- Formal parameters defined in the subprogram
header - Bound to storage when subprogram is called
through some other variables - e.g. void sumer(int num1, real num2)
- Actual parameters parameters used in the
subprogram call - Bound to formal parameters
- e.g. Sumer(10. 1.4)
6Parameters (cont.)
- Actual and formal parameter correspondences
- Positional parameters binding is based on
position - Keyword parameters binding is based on keyword
mapping - e.g. (Ada) sumer(num1gt 10, num2gt1.4)
- Defalut values C FORTRAN 90, Ada allow default
values for formal parameters - e.g. (C) void sumer(int Num1, real num2, int
flag 1)Caller sumer(10.1.4)
7Local referencing environment
- Local variables variables that are defined
inside the subprogram - Stack dynamic local variables
- Storage is allocated from stack
- Allows recursive programming
- Cost of time for allocation, initialization and
deallocation - Static local variables
- More efficient for direct addressing
- History sensitive
8Example I
- include ltstdio.hgt
- int count
- main( )
- int i
- for (i0 ilt10 i)
- test( )
-
- test( )
- int i
- static int count 0
- count count 1
virtual address space
testi
maini
run-time stack ptr
static var ptr
testcount
count
9Example I
- include ltstdio.hgt
- int count
- main( )
- int i
- for (i0 ilt10 i)
- test( )
-
- test( )
- int i
- static int count 0
- count count 1
Type-binding Storage-binding
count static static
maini static stack-dynamic
testi static stack-dynamic
testcount static static
10Parameter Passing Methods
- We discuss these at several different levels
- Semantic models
- in mode receive data from actual params.
- out mode transmit data to actual params
- Inout mode do both above
- Conceptual models of transfer
- Actual value is copied
- Move an access path
11Parameter-passing methods
12Pass-by-value
- Pass-by-value
- Use the value of the actual params to initialize
the corresponding formal params - Pascal, c, c
- EX.
main( ) int a 6 int b 4
Cswap(a, b) // a 6 // b 4
Cswap(int c, int d) int temp c c
d d temp
13Pass-by-value example
main( ) int a 6 int b 4
Cswap(a, b) // a 6 // b 4
temp6
d4
6
Cswap(int c, int d) int temp c c
d d temp
c6
c6
4
b4
b4
Cswap stack point
a6
a6
main stack point
14Pass-by-result
- Pass-by-result
- no value is transmitted to the subprogram
- the value of the formal para is passed back to
the actual para when the subprogram returns - Example (in a pseudo language)
caller( ) int a int b foo(a,
b) // a 6 // b 4
foo(int c, int d ) c 6 d 4
15Pass-by-result example
caller( ) int a int b foo(a,
b) // a 6 // b 4
d
4
4
foo(int c, int d ) c 6 d 4
c
6
6
b
foo stack point
a
caller stack point
16Pass-by-value-result
- Pass-by-value-result (a.k.a. pass-by-copy)
- the combination of pass-by-value and
pass-by-result - Ada
- Example (in Ada)
procedure swap(a in out integer, b in
out integer) is temp integer begin
temp a a b b
temp end swap
integer a 3 integer b 1
integer k10 k3 7 swap(a, b)
swap(b, kb)
17Pass-by-value-result example
integer a 3 integer b 1
integer k10 k3 7 swap(a, b)
swap(b, kb)
temp
3
temp
3
b1
3
b7
3
a3
1
a3
7
swap stack point
swap stack point
..
k3
7
3
procedure swap(a in out integer, b in
out integer) is temp integer begin
temp a a b b
temp end swap
k2
k1
k0
b1
3
7
a3
1
main stack point
18Pass-by-reference
- Pass-by-reference
- access path is transmitted to the called
subprogram efficient in terms of time space - access to formal paras are slower
- Example (in C)
caller( ) int a 3 int b 1
int k10 k3 7 swap(a, b)
swap(b, kb)
swap(int c, int d ) temp c c d
d temp
19Pass-by-reference example
caller( ) int a 3 int b 1
int k10 k3 7 swap(a, b)
swap(b, kb)
temp3
temp3
d2004
d2020
c2000
c2004
..
2024 2020 2016 2012 2008 2004 2000
swap stack point
swap stack point
k3
7
3
k2
k1
swap(int c, int d ) temp c c d
d temp
k0
b1
3
7
a3
1
caller stack point
20Pass-by-reference (cont)
temp3
temp3
caller( ) int a 3 int b 1 int
k10 k3 7 swap(a, b) swap(b,
kb)
d2004
d2020
c2000
c2004
..
2024 2020 2016 2012 2008 2004 2000
swap stack point
swap stack point
k3
7
3
k2
k1
swap(int c, int d ) temp c c d
d temp
k0
b1
3
7
a3
1
caller stack point
21Singlemensional array para
- C does not check the array subscript range ?
run-time error if our-of-bound access
void fun(int a) a3 77 main( )
int a10 a3 55 fun(a) //
a3 77
void fun(int a ) a3 77 main( )
int a10 a3 55 fun(a) //
a3 77
void fun(int a ) a13 77 //
run-time error main( ) int a10
a3 55 fun(a)
22Interesting C pointer usage
- fun(int a)
- a (int ) malloc(40)
- a5 1234
-
- main( )
- int array
- fun(array)
- printf(d, array5)
-
a51234
memory leakage!!
temp6
2060
d4
6
4
a0
2060
array0
fun stack
Segmentation fault!!
main stack
23Correct C pointer usage
- fun(int a)
- a5 1234
-
- main( )
- int array
- array (int ) malloc(40)
- fun(array)
- // array5 1234
-
a51234
temp6
2060
d4
6
4
a2060
a6
array0
2060
fun stack
main stack
24Array implementation
- One-dim array address calculation
- addr(aj) addr(a0) j elementSize
- int bounds10 // one int 4 bytes
- bounds0 1200 ?? bounds4
- Row-major allocation am,n a3, 3
- addr(ai,j) addr(a0,0) ((i n) j)
elementSize - a0, 3 4 7
- a1, 6 2 5 ? 3, 4, 7, 6, 2, 5, 1,
3, 8 - a2, 1 3 8
- a0,0 1200 ?? a1,2
1216
1220
25Multidimensional array para
- Compiler needs to know the declared size of the
multi-dim array to build the mapping function in
subprograms - C uses raw-major allocation
fun(int a ) a35 4321 main( )
int a1020 a35 1234
fun(a) // compiler error
fun(int a 25) a35 4321 main( )
int a1020 a35 1234
fun(a) // compiler error
fun(int a 20) a35 4321 main( )
int a1020 a35 1234
fun(a) // a35 4321
26Multidimensional array (cont)
fun(int a ) a345
4321 main( ) int a102025
a345 1234 fun(a) // compiler error
fun(int a 25) a345
4321 main( ) int a102025
a345 1234 fun(a) // compiler error
fun(int a 2025) a345
4321 main( ) int a102025
a345 1234 fun(a) // a345
4321
- Work around
- Use heap-dynamic variables for array
- int a a (int ) malloc(sizeof(int) m
n) - Pass the arrry variable alone with m and n
- fun(int a, int num_rows, int num_cols)
- ai, j (a i num_cols j)
27Function as parameters
int main( ) int Result int (pF)(int)
pF Plus Result Execute(3, pF)
// Result 6 pF Square Result
Execute(3, pF) // Result 9
int Plus (int num) return num num
int Square (int num) return num
num void Execute(int seed, int (pF)(int))
return pF(seed)
28Reference environment
- Referencing env
- shallow binding env of the call statement
- x 4
- deep binding env of the defined subprogram
- x 1
- C, C, Java.
- ad hoc binding env of the actual passing
statement - x 3
procedure SUB1 var x integer procedure
SUB2 begin write(x , x)
end procedure SUB3 var x integer
begin x 3 SUB4(SUB2)
end procedure SUB4(SUBX) var x
integer begin x 4 SUBX end begin
x 1 SUB3 end
29Generic Subprograms
- A generic or polymorphic subprogram is one that
takes parameters of different types on different
activations - A subprogram that takes a generic parameter that
is used in a type expression that describes the
type of the parameters of the subprogram provides
parametric polymorphism
30Without generic data structure
class Name char fullname64 class
Person char firstName64 char
lastName32
class PersonStack Person nodes50 int
stackptr public stack() stackptr
0 void push( Person data)
nodesstackptr data Person pop()
return nodesstackptr--
class NameStack Name nodes50 int
stackptr public stack() stackptr 0
void push( Name data)
nodesstackptr data Name pop()
return nodesstackptr--
int main(int argc, char argv )
NameStack DepartmentStack PersonStack
StudentsStack Name dep
DepartmentStack.push(dep)
31Generic data structure
class Name char fullname64 class
Person char firstName64 char
lastName32
int main(int argc, char argv )
stackltName,10gt DepartmentStack
stackltPerson,20gt StudentsStack
stackltName,50gt SchoolStack Name dep
DepartmentStack.push(dep)
templateltclass item, int max_itemsgt class stack
item nodesmax_items int
stackptr public stack() stackptr 0
void push( item data)
nodesstackptr data item pop()
return nodesstackptr--
32Generic function
- Example in C (similar in Ada)
- template ltclass Typegt
- Type max(Type first, Type second)
- return first gt second ? first second
-
- main( )
- int a, b, c
- char d, e, f
- c max(a, b) // code generation for int
max() - f max(d, e) // code generation for
char max() - b max(a, c) // no code generation
33Subprogram implementation
34General semantic
- Def The subprogram call and return operations of
a language are together called its subprogram
linkage
35Implementing Simple Subprograms
- Call Semantics
- 1. Save the execution status of the caller
- 2. Carry out the parameter-passing process
- 3. Pass the return address to the callee
- 4. Transfer control to the callee
36Implementing Simple Subprograms
- Return Semantics
- 1. If pass-by-value-result parameters are used,
move the current values of those parameters to
their corresponding actual parameters - 2. If it is a function, move the functional value
to a place the caller can get it - 3. Restore the execution status of the caller
- 4. Transfer control back to the caller
37Implementing Simple Subprograms
- Required Storage
- Caller status, parameters, return address, and
functional value (if it is a function) - The format, or layout, of the noncode part of an
executing subprogram is called an activation
record
38Subprogram implementation
- Activation record the layout of the call stack
for call-related data - Static-scoping PL implementation
- dynamic-scoping discussed later
- Two approaches to implementing nonlocal variables
accesses - static chains
- displays
Local variables
Parameters
Dynamic link
Static link
stack top
Return address
An activation record
39Scope example
Proc A reference environment Static scope
A ? main Dynamic scope A ? B ? main
- proc main
- var X1, X2
- proc A
- var X1, X2
- end
- proc B
- var X1, X2
- call A
- end
- call B
- end
40Static dynamic scope
- Procedure big
- var x integer
- procedure sub1
- begin
- x ? (1)
- end
- procedure sub2
- var x integer
- begin
- x ? (2)
- sub1
- end
- begin
- sub1 ? (3)
- x ? (4)
- sub2 ? (5)
- end
Static scope (3?1) x bigs x (4) x bigs
x (2) x sub2s x (5?1) x bigs x Dynamic
scope (3?1) x bigs x (4) x bigs x (2) x
sub2s x (5?1) x sub2s x
41Activation record
Procedure sub (var total real part
integer) var list array 1..5 of
integer sum real Begin End
- static link used for nonlocal variables
reference
- dynamic link points to the top of the AR of the
caller
The activation record for procedure sub
42Local reference example
Program MAIN_1 var P real procedure
A (X integer) var Y boolean
procedure C (Q boolean) begin C
end C begin A
C(Y) end A
procedure B (R real) var S, T
integer begin B A(S)
end B begin MAIN_1
B(P) end. MAIN_1
Local P
43Function value
?
1
Recursion example
Parameter n
1
Dynamic link
Static link
int factorial (int n) If (n lt1) return
1 else return (n factorial (n-1)) void
main() int value value factorial (3)
Return(to factorial)
If (n lt1)
Function value
?
2
return 1
Parameter n
2
Dynamic link
Static link
Return(to factorial)
Function value
?
6
6
Parameter n
3
Dynamic link
Static link
Return (to main)
Local value
?
44Static chain Display
- Static chain following the static chain for
nonlocal variable reference - costly
- nondeterministic
- Display the only widely used alternative to
static chain - static links are collected in a single array
called a display - exactly 2 steps to access nonlocal variables
45Nested Subprograms
- Technique 1 - Static Chains
- A static chain is a chain of static links that
connects certain activation record instances - The static link in an activation record instance
for subprogram A points to one of the activation
record instances of A's static parent - The static chain from an activation record
instance connects it to all of its static
ancestors
46Static Chains (continued)
- To find the declaration for a reference to a
nonlocal variable - You could chase the static chain until the
activation record instance (ari) that has the
variable is found, searching each ari as it is
found, if variable names were stored in the ari - Def static_depth is an integer associated with a
static scope whose value is the depth of nesting
of that scope
47Static Chains (continued)
- main ----- static_depth 0
- A ----- static_depth 1
- B ----- static_depth 2
-
-
-
-
- C ----- static_depth 1
48Static Chains (continued)
- Def The chain_offset or nesting_depth of a
nonlocal reference is the difference between the
static_depth of the reference and that of the
scope where it is declared - A reference can be represented by the pair
- (chain_offset, local_offset)
- where local_offset is the offset in the
activation record of the variable being referenced
49Nonlocal reference example
- program MAIN_2
- var X integer
- procedure BIGSUB
- var A, B, C integer
- procedure SUB1
- var A, D integer
- begin SUB1
- A B C lt-----------------------1
- end SUB1
- procedure SUB2(X integer)
- var B, E integer
- procedure SUB3
- var C, E integer
- begin SUB3
- SUB1
- E B A lt--------------------2
- end SUB3
- begin SUB2
- SUB3
50Example Pascal Program
- Call sequence for MAIN_2
- MAIN_2 calls BIGSUB
- BIGSUB calls SUB2
- SUB2 calls SUB3
- SUB3 calls SUB1
51Stack Contents at Position 1
52Example Pascal Program
At position 1 in SUB1 A - (0, 3) B - (1,
4) C - (1, 5) At position 2 in SUB3 E -
(0, 4) B - (1, 4) A - (2, 3) At position 3
in SUB2 A - (1, 3) D - an error E -
(0, 5)
53Nonlocal reference example
MAIN_2
var x
proc BIGSUB
BIGSUB
var A, B, C
proc SUB1
proc SUB2(X)
SUB2(7)
var A, D
A B C
SUB3 A X E
var C, E
proc SUB3
var C, E
SUB1 E B A
Main_2 calls Bigsub Bigsub calls sub2 Sub2 calls
sub3 Sub3 calls sub1
54Blocks
- Two Methods
- 1. Treat blocks as parameterless subprograms
- Use activation records
- 2. Allocate locals on top of the ari of the
subprogram - Must use a different method to access locals
- A little more work for the compiler writer
55Blocks
MAIN_5() int x, y, z while ( )
int a, b, c while ( )
int d, e while (
) int f, g
e
d
Block Variables
c
b and g
a and f
z
Locals
y
x
Activation Record instance For MAIN_5
56Implementing dynamic scoping
- Deep access the dynamic link chain is exactly
what needed to reference nonlocal variables in a
dynamic-scoped language - Shallow access each local variable is stored in
a separate stack
57Scope example
Proc A reference environment Static scope
A ? main Dynamic scope A ? B ? main
- proc main
- var X1, X2
- proc A
- var X1, X2
- end
- proc B
- var X1, X2
- call A
- end
- call B
- end
58Deep Access
Procedure C integer x, z begin x
u v end Procedure B integer w,
x begin end Procedure A
integer v, w begin end Program
MAIN_6 integer v, u begin end
MAIN_6 calls AA calls A A calls B B calls C
59Shallow Access
Procedure C integer x, z begin x
u v end Procedure B integer w,
x begin end Procedure A
integer v, w begin end Program
MAIN_6 integer v, u begin
end
MAIN_6 calls A A calls A A calls B B calls C
A
B
A
C
B
C
u
v
x
z
w