Subroutines and Control Abstraction

50
1 Subroutines and Control Abstraction Aaron Bloomfield CS 415 Fall 2005

description

Subroutines and Control Abstraction. Aaron Bloomfield CS 415 Fall 2005. Definitions. Function : subroutine that returns a value Procedure : subroutine that does not return a value. Review of Stack Layout. Storage consumed by parameters and local variables can be allocated on a stack - PowerPoint PPT Presentation

Transcript of Subroutines and Control Abstraction

Page 1: Subroutines and Control Abstraction

1

Subroutines and Control Abstraction

Aaron Bloomfield

CS 415

Fall 2005

Page 2: Subroutines and Control Abstraction

2

Definitions

• Function: subroutine that returns a value

• Procedure: subroutine that does not return a value

Page 3: Subroutines and Control Abstraction

3

Review of Stack Layout

• Storage consumed by parameters and local variables can be allocated on a stack

• Activation record contains arguments and/or return values, bookkeeping info, local variables, and/or temporaries

• On return, stack frame is popped from stack

Page 4: Subroutines and Control Abstraction

4

Review of Stack Layout (cont’d)

• Stack pointer: contains address of the first unused location at the top of the stack

• Frame pointer: contains address within frame

• Displacement addressing

• Objects with unknown size placed in variable-size area at top of frame

Page 5: Subroutines and Control Abstraction

5

Review of Stack Layout (cont’d)

Static chain

- Each stack frame contains a reference to the lexically surrounding subroutine

Page 6: Subroutines and Control Abstraction

6

Review of Stack Layout (cont’d)

Display

- used to reduce memory accesses to an object k levels out

Page 7: Subroutines and Control Abstraction

7

Calling Sequences

• Calling sequence: code executed by the caller immediately before and after a subroutine call

• Prologue

• Epilogue

Page 8: Subroutines and Control Abstraction

8

Calling Sequences (cont’d)

• Tasks on the way in (prologue)– Passing parameters, saving return address,

changing program counter, changing stack pointer, saving registers, changing frame pointer

• Tasks on the way out (epilogue)– Passing return parameters, executing

finalization code, deallocating stack frame, restoring saved registers and pc

Page 9: Subroutines and Control Abstraction

9

Case Study 1: C on the MIPS (example of RISC)

Page 10: Subroutines and Control Abstraction

10

Case Study 2: Pascal on the 680x0 (example of CISC)

Page 11: Subroutines and Control Abstraction

11

In-Line Expansion

• Allows certain subroutines to be expanded in-line at the point of call

• Avoids several overheads (space allocation, branch delays, maintaining static chain or display, saving and restoring registers)

Page 12: Subroutines and Control Abstraction

12

Implementations of In-line Expansion

• C++ uses keyword inline:inline int max( … ) { … }

• Ada:pragma inline (function_name);

• Pragmas make suggestions to the compiler. Compiler can ignore suggestion.

Page 13: Subroutines and Control Abstraction

13

In-line Expansion versus Macros

• in-line expansion– Semantically

preferable– Disadvantages?

• macros– Semantic problems– Syntactic problems

Page 14: Subroutines and Control Abstraction

14

Parameter Passing

Parameter Modes

Special-Purpose Parameters

Function Returns

Page 15: Subroutines and Control Abstraction

15

Parameter Passing Basics

• Parameters - arguments that control certain aspects of a subroutine’s behavior or specify the data on which they are to operate

• Global Variables are other alternative

• Parameters increase the level of abstraction

Page 16: Subroutines and Control Abstraction

16

More Basics

• Formal Parameters - parameter name in the subroutine declaration

• Actual Parameters – values passed to a subroutine in a particular call

Page 17: Subroutines and Control Abstraction

17

Parameter Modes

• Some languages define a single set of rules which apply to all parameters – C, Fortran, Lisp

• Some languages provide two or more sets of rules, which apply to different parameter modes– Algol, Pascal, Ada, Modula– We will discuss Ada Parameter Modes in

more detail

Page 18: Subroutines and Control Abstraction

18

Call by Value

• For P(X), two options are possible: Call by Value and Call by Reference

• Call by Value - provides P with a copy of X’s value

• Actual parameter is assigned to the corresponding formal parameter when subroutine is called, and the two are independent from then on

• Like creating a local or temporary variable

Page 19: Subroutines and Control Abstraction

19

Call by Reference

• Call by Reference – provide P with the address of X

• The formal parameter refers to the same object as the actual parameter, so that changes made by one can be seen by the other

Page 20: Subroutines and Control Abstraction

20

Language Specific Variations

• Pascal: Call by Value is the default, the keyword VAR denotes Call by Reference

• Fortran: all parameters passed by Reference

• Smalltalk, Lisp: Actual Parameter is already a reference to the object

• C: always passed by Value

Page 21: Subroutines and Control Abstraction

21

Value vs. Reference

• Pass by Value– Called routine cannot modify the Actual

Parameter

• Pass by Reference– Called routine can modify Actual Parameter

Page 22: Subroutines and Control Abstraction

22

Call by name

• Pretty much only in Algol• Re-evaluates the actual parameter on every use

– For actual parameters that are simple variables, it’s the same as call by reference

– For actual parameters that are expressions, the expression is re-evaluated on each access

• No other language ever used call by name…

Page 23: Subroutines and Control Abstraction

23

Safety and Efficiency

• Without language support, working with large objects that are not to be modified can be tricky– Call by Value:– Call by Reference:

• Examples of Language Support– Modula: READONLY parameter mode– C/C++: const keyword

Page 24: Subroutines and Control Abstraction

24

Ada Parameter Modes

Three parameter passing modes• In

– Passes information from the caller to the callee, can read but not write

– Call by Value• Out

– Passes information from the callee to the caller, can write but not read

– Call by Result (formal parameter is copied to actual parameter when subroutine exits)

• Inout - passes information both directions

Page 25: Subroutines and Control Abstraction

25

C++ Parameter Modes

C passes pointers as addresses, must be explicitly dereferenced when used

C++ has notion of references:

• Parameter passing: void swap (int &a, int &b)

• Variable References: int &j = i;• Function Returns: for objects that don’t

support copy operations, i.e. file buffers

Page 26: Subroutines and Control Abstraction

26

Review: references to functions

• When are scope rules applied?

– When the function is called?• Shallow binding

– When the reference is created?• Deep binding

Page 27: Subroutines and Control Abstraction

27

int max_score;

float scale_score (int raw_score) { return (float) raw_score / (float) max_score;}

float highest_score (int[] scores, function_ptr scaling_function) { float max_score = 0; foreach score in scores { float percent = scaling_function (score); if ( percent > max_score ) max_score = percent; } return max_score;}

main() { max_score = 50; int[] scores = ... print highest_score (scores, scale_score);}

function is called

reference is created

Page 28: Subroutines and Control Abstraction

28

Deep Binding

• Generally the default in lexically (statically) scoped languages

• Dynamically scoped languages tend to use shallow binding

Page 29: Subroutines and Control Abstraction

29

Closures

• Implementation of Deep Binding for a Subroutine– Create an explicit representation of the

current referencing environment and its bindings

– Bundle this representation with a reference to the subroutine

– This bundle is called a Closure

Page 30: Subroutines and Control Abstraction

30

Closures as Parameters

• Closures: a reference to a subroutine and its referencing environment

• Closures can be passed as a parameter

• Pascal, C, C++, Modula, Scheme

void apply_to_A (int (*f) (int),

int A[], int A_size)

{

int i;

for (i = 0; i < A_size; i++)

A[i] = f (A[i]);

}

Page 31: Subroutines and Control Abstraction

31

Special-Purpose Parameters

• Named Parameters - parameters that are not positional, also called keyword parameters. An Ada example:funcB (argA => 21, argB => 35);funcB (argB => 35, argA => 21);

• Some languages allow subroutines with a variable number of arguments: C, Lisp, etc.int printf (char *format, …) {…

• Standard Macros in function body to access extra variables

Page 32: Subroutines and Control Abstraction

32

Function Returns

• Some languages restrict Return types– Algol 60, Fortran: scalars only– Pascal, Modula: scalars or pointers only– Most imperative languages are flexible

• Return statements specify a value and also cause the immediate termination of the subroutine

Page 33: Subroutines and Control Abstraction

33

Generic Subroutines and Modules

Generic Subroutines

Generic Modules

Page 34: Subroutines and Control Abstraction

34

Generic Subroutines

• Large Programs often use the same data structures for different object types

• Characteristics of the queue data structure independent of the characteristics of the items in the queue

• Polymorphic subroutines– Argument types are incompletely specified– Can cause slower compilation– Sacrifice compile-time type checking

Page 35: Subroutines and Control Abstraction

35

Generic Modules

• Similar subroutines are created from a single piece of source code

• Ada, Clu, Modula-3

• C++ templates

• Similar to macros, but are actually integrated into the rest of the language

• Follow scope, naming, and type rules

Page 36: Subroutines and Control Abstraction

36

Exception Handling

Page 37: Subroutines and Control Abstraction

37

Exceptions

• Exceptions are an unexpected or unusual condition that arises during program execution.

• Most common are various sorts of run-time errors (ex. encountering the end of a file before reading a requested value)

Page 38: Subroutines and Control Abstraction

38

Handling Exceptions

• Exception handling was pioneered by PL/I• Utilized an executable statement of the following

form:ON condition statement

• Handler is nested inside and is not executed on the ON statement but is remembered for future reference.

• Executes exception when exception condition is encountered

Page 39: Subroutines and Control Abstraction

39

Handling Exceptions

• Recent languages provide exception-handling facilities where handlers are lexically bound to blocks of code.

• General rule is if an exception isn’t handled in the current subroutine, then the subroutine returns and exception is raised at the point of call.

• Keeps propagating up dynamic chain until exception is handled.

• If not handled a predefined outermost handler is invoked which will terminate the program.

Page 40: Subroutines and Control Abstraction

40

3 Main Handler Uses

• 1) Perform some operation that allows the program to recover from the exception and continue executing.

• 2)If recovery isn’t possible, handler can print helpful message before termination

• 3)When exception occurs in block of code but can’t be handled locally, it is important to declare local handler to clean up resources and then re-raise the exception to propagate back up.

Page 41: Subroutines and Control Abstraction

41

Defining Exceptions

• Ada

declare empty_queue : exception;

• Modula-3

EXCEPTION empty_queue;

• C++ and Javaclass empty_queue{};

Page 42: Subroutines and Control Abstraction

42

Exception Propagation

try{...//protected block of code...}catch(end_of_file) {...}catch(io_error e) {//handler for any io_error other than end_of_file...}catch(…) {//handler for any exception not previously named//… is a valid token in the case in C++, doesn’t //mean code has been left out.}

Page 43: Subroutines and Control Abstraction

43

Implementing Exceptions

• Can be made as a linked list stack of handlers.

• When control enters a protected block, handler for that block is added to head of list.

• Propagation down the dynamic chain is done by a handler in the subroutine that performs the work of the subroutine’s epilogue code and the reraises the exception.

Page 44: Subroutines and Control Abstraction

44

Problems With This Implementation

• Incurs run-time overhead in the common case

• Every protected block and every subroutine begins with code to push a handler onto the handler list, and ends with code to pop it off the list.

Page 45: Subroutines and Control Abstraction

45

A Better Implementation

• Since blocks of code in machines can translate to continuous blocks of machine instructions, a table can be generated at compile time that captures the correspondence between blocks and handlers

Starting Address of Code Block

Address of Corresponding Handler

Page 46: Subroutines and Control Abstraction

46

Implementing Exceptions

• Table is sorted by the first field of the table

• When an exception occurs the system performs a search of the table to find the handler for the current block.

• If handler re-raises the exception, the process repeats.

Page 47: Subroutines and Control Abstraction

47

Coroutines

Page 48: Subroutines and Control Abstraction

48

Coroutines

• Coroutines are execution contexts that exist concurrently, but execute one at a time, and transfer control to each other explicitly, by name.

• They can implement iterators and threads.

Page 49: Subroutines and Control Abstraction

49

Stack Allocation

• Since they are concurrent they can’t share a single stack because subroutine calls and returns aren’t LIFO

• Instead the run-time system uses a cactus stack to allow sharing.

Page 50: Subroutines and Control Abstraction

50

Transfer

• To go from one coroutine to another the run-time system must change the PC, stack, and register contents. This is handled in the transfer operation.