• No results found

Scope, Functions, and Storage Management

N/A
N/A
Protected

Academic year: 2022

Share "Scope, Functions, and Storage Management"

Copied!
15
0
0

Loading.... (view fulltext now)

Full text

(1)

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 … end

ML:

let … in … end

Blocks

• 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

(2)

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

(3)

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:

(4)

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) };

};

...

(5)

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:

(6)

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:

(7)

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:

(8)

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

(9)

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 : : :

(10)

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

(11)

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:

(12)

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)

(13)

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.

(14)

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

(15)

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

References

Related documents