L. Dillon, CSE 452, Fall 2008 1
Scope, Functions, and Storage Management
Block-structured languages and stack storage In-line
• Blocks activation records
−
storage for local, global variables
− First-
• order functions parameter passing
−
tail recursion and iteration
−
• Higher-order functions
(next set of overheads)deviations from stack discipline
−
language expressiveness
− => implementation complexity
L. Dillon, CSE 452, Fall 2008 2
Block
• is a group of consecutive instructions that may contain local declarations
Scope
−
of a local declaration is confined to the declaring block.
Blocks may be
− nested.
Block-Structured Languages
{ int x = 0;
{ int y = 10;
for (int n = 0; n < y; n++) { x = x + n;
} } }
_ b b ` b b a _ b
` b a _ ` a Memory management
•
Allocate space for variables on entering the block.
−
L. Dillon, CSE 452, Fall 2008 3
Examples In-line blocks in common languages
•
C, Python:
− { … }
Algol, Pascal, Ada:
−
begin … endML:
−
let … in … endBlocks
• associated with functions or procedures in most (all?) languages
Topics:
• access to local variables, parameters, and global variables in block-structured memory management
L. Dillon, CSE 452, Fall 2008 4
Translation to an abstract machine model Very simple machine model:
code
• memory:
array of machine instructions
−
contents is static
−
• data memory:
array of data values
−
contents change during execu-
− tion
program
• counter (PC): contains label (index) of the next instruc- tion
machine
• cycle: fetch-incre- ment-decode-execute
Recall: Abstract machine model
. . .
. . .
Code Data
Program Counter
L. Dillon, CSE 452, Fall 2008 5
Simple Memory Model
Registers
.. .
Program Counter
Environment Pointer
Code
.. .
Data
.. ... .
_ b b ` Stack b b a _ b b ` Heap b b a
L. Dillon, CSE 452, Fall 2008 6
Registers, Code segment, Program counter
•
Ignore registers
−
Details of instruction set will not matter
−
Data Segment
• Stack
− contains data related to block entry/exit and local to block
Activation record◊ — data for a block (function)
− Heap contains data
whose lifetime is not confined to the lifetime of the block that declares it
◊
whose size cannot be determined a priori on entry to the declaring block
◊
Environment
− pointer points to base of current activation record
Block entry: add new activation record to stack◊
Block exit: remove most recent activation record
◊
Basic Memory Management Only
L. Dillon, CSE 452, Fall 2008 7
Scope of a declaration (identifier)
•
Region of program text where the declaration is visible (a use of
−
the identifier refers to the data created by the declaration) Lifetime
• of a declaration (identifier)
Period of time during execution of a program when a location is
−
allocated as a result of that declaration (the identifier is bound to this location)
Some Basic Concepts
Inner declaration of
◊ x hides outer one.
Called a “hole in scope”
◊
Lifetime of outer
◊ x includes time when
inner block is executed Lifetime
◊ ! scope
Lines indicate “
◊ contour model” of scope.
{ int x = ...;
{ int y = ...;
{ int x = ...;
...
};
};
};
L. Dillon, CSE 452, Fall 2008 8
Activation
• record
Data structure stored on run-time stack
−
Contains space for local variables
−
May need space for variables and intermediate results
−
e.g,◊ (y+z), (y-z) below
Example
•
In-Line Blocks
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
Push AR with space for x, y Set value of y
Push AR with space for z & set its value Set value of x
Pop record for inner block Pop record for outer block
L. Dillon, CSE 452, Fall 2008 9
Activation Record (AR) for In-line Block
Control Link (CL) Local Variables
Intermediate Results
Control Link (CL) Local Variables
Intermediate Results
Control link (CL)
•
Pointer to previous record on
− stack Push
• new AR on stack:
Set CL in new AR to old EP
−
Set EP to base of new AR
− Pop
• record off stack Follow CL of current record to
−
reset EP for caller
Environment pointer (EP) Environment pointer
L. Dillon, CSE 452, Fall 2008 10
Activation Record (AR) for In-line Block
Control Link (CL) Local Variables
Intermediate Results
Control Link (CL) Local Variables
Intermediate Results
Control link (CL)
•
Pointer to previous record on
− stack Push
• new AR on stack:
Set CL in new AR to old EP
−
Set EP to base of new AR
− Pop
• record off stack Follow CL of current record to
−
reset EP for caller
Environment pointer (EP)
L. Dillon, CSE 452, Fall 2008 11
Activation Record (AR) for In-line Block
Control Link (CL) Local Variables
Intermediate Results
Control Link (CL) Local Variables
Intermediate Results
Control link (CL)
•
Pointer to previous record on
− stack Push
• new AR on stack:
Set CL in new AR to old EP
−
Set EP to base of new AR
− Pop
• record off stack Follow CL of current record to
−
reset EP for caller
Environment pointer (EP) Environment pointer
L. Dillon, CSE 452, Fall 2008 12
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
Example
CL:
x: ~11
y: 5
CL:
z: 6
y+z: 11 y-z: ~1
PC:
EP:
L. Dillon, CSE 452, Fall 2008 13
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
Example
CL:
x: ~11
y: 5
CL:
z: 6
y+z: 11 y-z: ~1 EP: PC:
L. Dillon, CSE 452, Fall 2008 14
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
Example
CL:
x: ~11
y: 5
CL:
z: 6
y+z: 11 y-z: ~1
PC:
EP:
L. Dillon, CSE 452, Fall 2008 15
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
Example
CL:
x: ~11
y: 5
CL:
z: 6
y+z: 11
y-z: ~1 PC:
EP:
L. Dillon, CSE 452, Fall 2008 16
Scoping Rules
Global and local variables
•
− , y are local to outer block x
− is local to inner bock z
− , y are global to inner block x Scope Rules
•
Static scope
−
global refers to declaration in closest enclosing block
◊
Dynamic scope
−
global refers to most recent activation record with a declaration for id
◊
These
−
are same until we consider function calls.
...
{ int x;
int y = 5;
{ int z = y + 1;
x = (y+z)*(y-z) };
};
...
L. Dillon, CSE 452, Fall 2008 17
Functions and Procedures Syntax of procedures (Algol) and functions (C)
•
procedure P (<pars>) <type> f(<pars>) begin {
<local vars> <local vars>
<proc body> <function body>
end; }
Activation
• record must include space for
parameters
−
return address
−
return value (an intermediate result)
−
possibly, other intermediate results
−
location where caller expects return value to be when the call returns
−
value to restore caller's EP (control link)
−
L. Dillon, CSE 452, Fall 2008 18
Activation Record for Functions
Control Link (CL) Return Address (RA)
Return-Result Address (RRA) Parameters
Local Variables Intermediate
Results
Return address
•
Location of instruction to
−
execute on function return Return-result address
•
Location where return result
−
is to be put for later retrieval by caller
Parameters
•
Locations for argument val-
−
ues provided by the caller
L. Dillon, CSE 452, Fall 2008 19
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 20
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 21
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 22
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 23
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 24
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 25
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
EP:
PC:
L. Dillon, CSE 452, Fall 2008 26
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 27
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
PC:
EP:
L. Dillon, CSE 452, Fall 2008 28
main { ...
... = gcd(24, 9);
... }
int gcd(int n,int m) { if (n < m) then return gcd(m,n);
elseif (n mod m == 0) return m;
else return
gcd(m,n mod m) ;
} ...
gcd(24,9): 3 ...
CL:
RA: a RRA:
n: 24 m: 9 gcd(...): 3
CL:
RA: b RRA:
n: 9 m: 6 gcd(...): 3
Example
CL:
RA: b RRA:
n: 6 m: 3 gcd(...):
a:
b:
EP:
PC:
L. Dillon, CSE 452, Fall 2008 29
Topics for first-order functions Parameter passing
•
use ML reference cells to describe parameter passing
−
pass by-value
◊
pass by-reference
◊
Access
• to global variables
global variables are contained in an activation record higher “up”
−
the stack Tail
• recursion
an optimization for certain recursive functions
−
L. Dillon, CSE 452, Fall 2008 30
General terminology: L-values and R-values
•
Assignment y := x + 3
−
Identifier on left is a L-value, refers to a location
◊
Identifier on right is an R-value, refers to contents of a location
◊
In ML, different types for L-values and R-values
•
val x = 5;
−
val x = 5 : int (* non-assignable integer value bound to 5 *) val y = ref x;
−
val y = ref 5 : int ref (* loc whose contents must be int, initialized to 5 *)
ML assignment
•
y := x+3;− (* place value of x+3 in cell y; requires x:int and y:int ref *) val it = () : unit
y := !y + 3;
− (* add 3 to contents of y, store in location; requires y:int ref*) val it = () : unit
ML imperative constructs
L. Dillon, CSE 452, Fall 2008 31
Pass by-reference
•
Caller places L-value (address) of actual parameter in AR
−
Function can assign to variable that is passed
−
Pass by-value
•
Caller places R-value (contents) of actual parameter in AR
−
Function cannot change value of caller’s variable
−
Reduces aliasing
−
Aliases◊ : Two names that refer to the same location
ML imperative constructs
L. Dillon, CSE 452, Fall 2008 32
Pseudocode:
int f ( int x ) { x = x+1;
return x;
}
var y = 0;
print (f(y)+y);
fun f (z : int) = let x = ref z in x := !x+1; !x end;
y = ref 0 : int ref;
f(!y) + !y;
fun f (x : int ref) = ( x := !x+1;
!x );
val y = ref 0 : int ref;
f(y) + !y;
Example
Pass b y-referenc
e Pass by-value
L. Dillon, CSE 452, Fall 2008 33
Exercise
Pseudocode:
int f ( int x ) { x = x+1;
return x;
}
int y = 0;
int z = (f(y)+y);
ML:
fun f (w : int) = let val x = ref w in x := !x+1;
!x end;
val y = ref 0 : int ref;
val z = f(!y) + !y;
fun f (x : int ref) = ( x := !x+1;
!x );
val y = ref 0 : int ref;
val z = f(y) + !y;
Pass by-reference Pass by-value What is the final value of z in each case?
L. Dillon, CSE 452, Fall 2008 34
Example
var x = 1;function g(z) {
return x+z; } :PC function f(y) {
var x = y+1;
if (x >= 4)
{ return g(y*x); } else { return f(x) }}
print f(3);
print f(2);
(main) : : : x: 1 (f) CL:
: : : y: 3 x: 4 : : : (g) CL:
: : : z: 12
: : :
Access to global variables
Two possible scoping conventions
Static scope: refers to closest enclos-−
ing block declaring the identifier Dynamic scope: refers to most recent
−
AR on stack declaring the identifier
EP:
(main) : : : x: 1 (f) CL:
: : : y: 2 x: 3 : : : (f) CL:
: : : y: 3 x: 4 : : : (g) CL:
: : : z: 12
: : : EP:
L. Dillon, CSE 452, Fall 2008 35
Example
var x = 1;function g(z) {
return x+z; } :PC function f(y) {
var x = y+1;
if (x >= 4)
{ return g(y*x); } else { return f(x) }}
print f(3);
print f(2);
Implementing dynamic scope rules
Simple implementation:
Store identifiers and values in AR
−
Search ARs, starting from the EP and
−
following CL's for most recent AR declaring the identifier
(main) : : : x: 1 (f) CL:
: : : y: 3 x: 4 : : : (g) CL:
: : : z: 12 : : : EP:
(main) : : : x: 1 (f) CL:
: : : y: 2 x: 3 : : : (f) CL:
: : : y: 3 x: 4 : : : (g) CL:
: : : z: 12 : : : EP:
L. Dillon, CSE 452, Fall 2008 36
Example
var x = 1;function g(z) {
return x+z; } :PC function f(y) {
var x = y+1;
if (x >= 4)
{ return g(y*x); } else { return f(x) }}
print f(3);
print f(2);
(main) : : : x: 1 (f) CL:
AL:
y: 3 x: 4 : : : (g) CL:
AL:
z: 12 : : : EP:
(main) : : : x: 1 (f) CL:
AL:
y: 2 x: 3 : : : (f) CL:
AL:
y: 3 x: 4 : : : (g) CL:
AL:
z: 12 : : : EP:
Implementing static scope rules
Access link (AL):
Points to AR of most recent enclosing
− block
Follow ALs to AR declaring the identifier
−
Number of "steps" to declaring AR de-
−
termined statically
(main) : : : x: 1 (f) CL:
y: 3 x: 4 : : : (g) CL:
z: 12 : : :
L. Dillon, CSE 452, Fall 2008 37
AR for static scope rules
Control Link (CL) Access Link (AL) Return Address (RA)
Return-Result Address (RRA) Parameters
Local Variables Intermediate Results (IR)
To simplify pictures, we generally don't show all entries in activation records—we show just those entries relevant to the point being illustrated.
Control link
•
Link to activation record of most recent
−
block (i.e, of the caller)
Access link
•
Link to AR of most recent enclosing block
−
in program text
Difference
•
Control link depends on
−
dynamic behavior of program Determine
◊ dynamic chain: start with most recent AR and follow CL's
Access link depends on static form of pro-
− gram text
Determine
◊ static chain: start with most recent AR and follow AL's
Defines the
◊ referencing environment
L. Dillon, CSE 452, Fall 2008 38
Example: Implementing static scope rules for ML
Treat each declaration as starting a new (in-line) block.
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) then g(y*x) else f(x) end;
f(3);
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) then g(y*x) else f(x) end;
f(3);
L. Dillon, CSE 452, Fall 2008 39
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 40
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f EP:
:PC
L. Dillon, CSE 452, Fall 2008 41
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 42
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 43
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f
:PC Since f is local, it is
found in the AR pointed to by EP (no contours from the use to the decl) EP:
L. Dillon, CSE 452, Fall 2008 44
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 45
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 46
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
g is found in the AR reached by following 2 AL's (2 contours from the use and the decl) EP:
L. Dillon, CSE 452, Fall 2008 47
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f EP:
:PC
L. Dillon, CSE 452, Fall 2008 48
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP: x is found in the AR
reached by following 2 AL's (2 contours from the use to the decl)
L. Dillon, CSE 452, Fall 2008 49
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13
CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 50
val x = 1;
fun g(z) = x+z;
fun f(y) = let
val x = y+1 in
if (x >= 4) g(y*x) else f(x) end;
f(3);
Example: First-order functions with static scope
x: 1 CL:
AL:
g: a CL:
AL:
f: b f(3): 13 CL:
AL:
y: 3 x: 4 f(x):
g(..): 13 CL:
AL:
z: 12 a:
b:
For new in-line block
◊
−new AL := EP To
◊ initialize fun var f:
−f := location in code seg- ment to jump to when f is invoked
To
◊ find declaration for id Follow
− AL's to closest AR declaring id
− of AL's determined by # the number of contours from the use of id to the declaration of id For
◊ call to fun f:
−AL in new AR := ref to the AR declaring f
−PC := f :PC
EP:
L. Dillon, CSE 452, Fall 2008 51
Dynamic scope
In AR, store both• id and value of local variable
For a global reference to
• id, search
AR's along the dynamic chain (follow CL's) to find first one declaring id In general, can't statically determine:
•
How many CL's to a declaring AR
− Where
− id will be within the AR If some such AR will be found
−
Static scope
In AR, store AL to most recent AR of
•
enclosing block For a global reference to
• id, walk
down static chain (follow AL's) to the appropriate AR
Compiler statically determines
•
Number of AL's to the declaring AR
−
Offset from base of the declaring
−
AR and size of location for id
Comparison of scoping implementations
Most current languages use static scoping for declarations of variables and functions.
Dynamic scoping is still used in some special-purpose languages (e.g., TeX/LaTeX), macros and exceptions.
What implications can be drawn regarding comparative Run-time efficiency (both time efficiency and space efficiency)?
• Safety?
•
L. Dillon, CSE 452, Fall 2008 52
Dynamic scope
In AR, store both• id and value of local variable
For a global reference to
• id, search
AR's along the dynamic chain (follow CL's) to find first one declaring id In general, can't statically determine:
•
How many CL's to a declaring AR
− Where
− id will be within the AR If some such AR will be found
−
Static scope
In AR, store AL to most recent AR of
•
enclosing block For a global reference to
• id, walk
down static chain (follow AL's) to the appropriate AR
Compiler statically determines
•
Number of AL's to the declaring AR
−
Offset from base of the declaring
−
AR and size of location for id
Comparison of scoping implementations
Most current languages use static scoping for declarations of variables and functions.
Dynamic scoping is still used in some special-purpose languages
(e.g., TeX/LaTeX), macros and exceptions.
L. Dillon, CSE 452, Fall 2008 53
Tail recursion
(First order case)
Function
• g makes a tail call to function f if Function
− f returns the value returned by the call to g Example
:- fun digits(x) =
= if (x<0) then digits(~x)
= else if (x<10) then 1
= else 1 + digits(x div 10);
Optimization
•
Can pop activation record on a tail call
−
Especially useful for recursive tail call
−
next activation record has exactly same form
◊
not a tail call tail call
- (* compute digits using tail
= recursive helper function *) - fun tdigits(n, x) =
= if ( x < 10 ) then n
= else tdigits(n+1, x div 10);
- fun digits(x) =
= if (x < 10) then tdigits(1, ~x)
= else tdigits(1, x);
- digits 125;
Example
(digits 125): CL:
RRA:
x: 125 tdigits(...):
CL:
RRA:
n: 1 x: 125 tdigits(...):
CL:
RRA:
n: 2 x: 12 tdigits(...):
CL:
RRA:
n: 3 x: 1
Unoptimized:
On return, each activation copies the
−
return value into the AR of its caller and then pops its own AR
- (* compute digits using tail
= recursive helper function *) - fun tdigits(n, x) =
= if ( x < 10 ) then n
= else tdigits(n+1, x div 10);
- fun digits(x) =
= if (x < 10) then tdigits(1, ~x)
= else tdigits(1, x);
- digits 125;
Example
(digits 125): CL:
RRA:
x: 125 tdigits(...):
CL:
RRA:
n: 1 x: 125 tdigits(...):
CL:
RRA:
n: 2 x: 12 tdigits(...):
CL:
RRA:
n: 3 x: 1
Optimization 1. For tail call new RRA := the RRA in AR of caller
−
No need for a location for the value
−
returned by tail call
No need to copy back value after
−
return from a tail call
- (* compute digits using tail
= recursive helper function *) - fun tdigits(n, x) =
= if ( x < 10 ) then n
= else tdigits(n+1, x div 10);
- fun digits(x) =
= if (x < 10) then tdigits(1, ~x)
= else tdigits(1, x);
- digits 125;
Example
Optimization 2.
For tail recursive call:
Pop caller's AR before pushing AR
−
for tail call = reuse the caller's AR in place
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 1 x: 125
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 2 x: 12
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 3 x: 1
L. Dillon, CSE 452, Fall 2008 57 (digits...):
CL:
RRA:
x: 125 CL:
RRA:
n: 1 x: 125
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 2 x: 12
Example: tail recursion and iteration
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 3 x: 1
fun tdigits(n, x) = if ( x < 10 ) then n else tdigits(n+1, x div 10);
tdigits(1, 125);
fun tdigits(x) = let
val n = ref 1 in
while not( !x < 10) do ( n := !n + 1;
x := !x div 10) end;
tdigits(1, 125);
A tail recursive function is equiva- lent to an iterative loop.
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 1 x: 125
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 2 x: 12
Example: tail recursion and iteration
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 3 x: 1
fun tdigits(n, x) = if ( x < 10 ) then n else tdigits(n+1, x div 10);
tdigits(1, 125);
fun tdigits(x) = let
val n = ref 1 in
while not( !x < 10) do ( n := !n + 1;
x := !x div 10) end;
tdigits(1, 125);
L. Dillon, CSE 452, Fall 2008 58
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 1 x: 125
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 2 x: 12
Example: tail recursion and iteration
(digits...): CL:
RRA:
x: 125 CL:
RRA:
n: 3 x: 1
fun tdigits(n, x) = if ( x < 10 ) then n else tdigits(n+1, x div 10);
tdigits(1, 125);
fun tdigits(x) = let
val n = ref 1 in
while not( !x < 10) do ( n := !n + 1;
x := !x div 10) end;
tdigits(1, 125);
A tail recursive function is equiva- lent to an iterative loop.
initial value test
body