Scope and Code Generation

Slides:



Advertisements
Similar presentations
Prof. Necula CS 164 Lecture 141 Run-time Environments Lecture 8.
Advertisements

(1) ICS 313: Programming Language Theory Chapter 10: Implementing Subprograms.
Chapter 10 Implementing Subprograms. Copyright © 2012 Addison- Wesley. All rights reserved. 1-2 Chapter 10 Topics The General Semantics of Calls and Returns.
ISBN Chapter 10 Implementing Subprograms.
1 Storage Registers vs. memory Access to registers is much faster than access to memory Goal: store as much data as possible in registers Limitations/considerations:
CS 536 Spring Run-time organization Lecture 19.
ISBN Chapter 10 Implementing Subprograms.
ISBN Chapter 10 Implementing Subprograms.
Run-Time Storage Organization
Run time vs. Compile time
The environment of the computation Declarations introduce names that denote entities. At execution-time, entities are bound to values or to locations:
Run-time Environment and Program Organization
ISBN Chapter 10 Implementing Subprograms –Semantics of Calls and Returns –Implementing “Simple” Subprograms –Implementing Subprograms with.
1 CSCI 360 Survey Of Programming Languages 9 – Implementing Subprograms Spring, 2008 Doug L Hoffman, PhD.
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
Chapter 10 Implementing Subprograms. Copyright © 2007 Addison-Wesley. All rights reserved. 1–2 Semantics of Call and Return The subprogram call and return.
Shallow Versus Deep Copy and Pointers Shallow copy: when two or more pointers of the same types point to the same memory – They point to the same data.
“is a”  Define a new class DerivedClass which extends BaseClass class BaseClass { // class contents } class DerivedClass : BaseClass { // class.
ISBN Chapter 10 Implementing Subprograms.
Chapter 10 Implementing Subprograms. Copyright © 2012 Addison-Wesley. All rights reserved.1-2 Chapter 10 Topics The General Semantics of Calls and Returns.
Chapter 5: Programming Languages and Constructs by Ravi Sethi Activation Records Dolores Zage.
1 Copyright © 1998 by Addison Wesley Longman, Inc. Chapter 9 Def: The subprogram call and return operations of a language are together called its subprogram.
Functions and Procedures. Function or Procedure u A separate piece of code u Possibly separately compiled u Located at some address in the memory used.
Basic Semantics Associating meaning with language entities.
Recursion. What is recursion? Rules of recursion Mathematical induction The Fibonacci sequence Summary Outline.
ISBN Chapter 10 Implementing Subprograms.
Implementing Subprograms What actions must take place when subprograms are called and when they terminate? –calling a subprogram has several associated.
Run-Time Storage Organization Compiler Design Lecture (03/23/98) Computer Science Rensselaer Polytechnic.
Chapter 6 Introduction to Defining Classes. Objectives: Design and implement a simple class from user requirements. Organize a program in terms of a view.
1 Chapter 10 © 2002 by Addison Wesley Longman, Inc The General Semantics of Calls and Returns - Def: The subprogram call and return operations of.
RUNTIME ENVIRONMENT AND VARIABLE BINDINGS How to manage local variables.
Quick Review of OOP Constructs Classes:  Data types for structured data and behavior  fields and methods Objects:  Variables whose data type is a class.
10-1 Chapter 10: Implementing Subprograms The General Semantics of Calls and Returns Implementing “Simple” Subprograms Implementing Subprograms with Stack-Dynamic.
ISBN Chapter 10 Implementing Subprograms.
Implementing Subprograms
Subprograms - implementation. Calling a subprogram  transferring control to a subprogram: save conditions in calling program pass parameters allocate.
ISBN Chapter 10 Implementing Subprograms.
Code Generation Instruction Selection Higher level instruction -> Low level instruction Register Allocation Which register to assign to hold which items?
Design issues for Object-Oriented Languages
Implementing Subprograms
Storage Allocation Mechanisms
Polymorphism in Methods
Chapter 10 : Implementing Subprograms
Run-Time Environments Chapter 7
Implementing Subprograms Chapter 10
Implementing Subprograms
Implementing Subprograms
COMPILERS Activation Records
Implementing Subprograms
Subprograms The basic abstraction mechanism.
Run-time organization
Procedures (Functions)
Programming Language Concepts (CIS 635)
The Procedure Abstraction Part IV: Allocating Storage & Establishing Addressability Copyright 2003, Keith D. Cooper, Ken Kennedy & Linda Torczon, all rights.
Functions and Procedures
CSC 253 Lecture 8.
Implementing Subprograms
Chapter 10: Implementing Subprograms Sangho Ha
Implementing Subprograms
CSC 253 Lecture 8.
Implementing Subprograms
Implementing Subprograms
Topic 3-b Run-Time Environment
What time is it?. What time is it? Major Concepts: a data structure model: basic representation of data, such as integers, logic values, and characters.
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
UNIT V Run Time Environments.
Implementing Subprograms
Activation records Programming Language Design and Implementation (4th Edition) by T. Pratt and M. Zelkowitz Prentice Hall, 2001 Section
Implementing Subprograms
Chapter 10 Def: The subprogram call and return operations of
Presentation transcript:

Scope and Code Generation Pat Morin COMP 3002

Scope Scoping rules define how variable names are looked up when a program is run or compiled We have seen how to implement scoping rules in a typechecker How does it work in a code generator?

Run-time Environments During execution, each time a function call is made, a new stack frame is created to hold all the parameters and local variables for that function call Local variables are assigned a position within their stack frame A frame pointer (fp) keeps track of the top of the current stack frame

Example of stack frame layout int factorial(int n) { if (n == 1) return 1; int t = factorial(n-1); return n * t; } n (4 bytes) t (4 bytes)

A Runtime Example fp n 5 t undefined factorial(5) n 4 t undefined

Discussion The compiler assigns, to each variable and parameter, a location within the current stack frame Operations on local variables are compiled into operations on memory locations relative to the frame pointer (fp) But now all variable references are to local variables We assume static lexical scoping

A more complicated example int odd_factorial(int q) { int factorial(int n) { if (n == 1) return q; int t = factorial(n-1); return n * t; } if (q % t == 0) return t; return factorial(t); q (4 bytes) n (4 bytes) t (4 bytes)

A Runtime Example fp How do we access q within factorial? q 5 even_factorial(5) n 5 t undefined factorial(5) n 4 t undefined factorial(4) n 3 t undefined factorial(3) n 2 t 1 factorial(2) n 1 t undefined fp

Solution 1 Each function has a static level of scope Global scope - level 0 even_factorial – level 1 factorial – level 2 Each stack frame contains an extra pointer fpp that points to the stack frame at the next highest level (fpp is actually an implicit parameter)

A Runtime Example Now we know how to find q from within any recursive call q is at memory location fpp + 0 q 3 even_factorial(3) fpp n 3 t undefined factorial(3) fpp n 2 t 1 factorial(2) fpp n 1 t undefined factorial(1) fp

Solution 2 The problem with solution 2 is that it becomes increasingly expensive to access elements that are further away in scope Current level i Variable to access is at level j>i We must follow j-i fpp pointers To speed this up, we can use a global array frame_pointers frame_pointers[i] is the frame pointer to the currently active level i frame

Frame pointer array example q 3 even_factorial(3) n 3 t undefined factorial(3) n 2 t 1 factorial(2) n 1 t undefined factorial(1) fp

Solution 2 (Cont'd) Within a function at level i Save tmp = frame_pointers[i] Set frame_pointer[i] = fp (current frame pointer) Before returning, restore frame_pointers[i] = tmp When accessing a variable at level i from a level j > i we can get the correct frame pointer just by looking at frame_pointers[i]

Solution 1 versus Solution 2 Whether to use Solution 1 or 2 depends on how often variables at higher levels of scope are accessed Solution 1 is more costly when accessing variables that are at much higher scope levels Solution 2 increases the cost of every function call but makes all variable accesses constant time

What About Objects? For compilers, objects are just structures When calling a method on an object, an implicit pointer to the object is passed (this or self) to the method Inheritance is handled by having the child class inherit the structure of the parent and then add on its own elements

Inheritance Example Any method that assumes the memory layout of a Book can be used on a Novel or a Collection Book title -> String Novel author -> String Collection editor -> String Book title (4 bytes) Novel title (4 bytes) Collection title (4 bytes) author (4 bytes) editor (4 bytes

"Virtual" Methods For each "virtual" object method, a new instance variable can be created When a child class overrides a method in a parent class, the instance variable is just overridden Book title (4 bytes) fnPrint -> printBook Novel title (4 bytes) fnPrint -> printNovel Collection title (4 bytes) fnPrint -> printColl author (4 bytes) editor (4 bytes)

"Virtual" Methods (Cont'd) Virtual methods require two extra levels of indirection Lookup the function address in this or self (1 level) Load the function address and call it For this reason, some languages (C++ and Java) mix "virtual" and non-virtual functions In C++ the virtual keyword is used to specify virtual functions (all others are non-virtual) In Java, the final keyword is used to specify non-virtual functions (these can't be overridden by a subclass)

Summary A compiler must resolve occurrences of a variable to the memory location of that variable For static lexical scoping, this is done using parent frame pointers (fpp) 2 solutions: 1 - slower lookup for deeply nested functions 2 - slower function calls but faster lookup For objects, this is even easier Objects inherit their structure from their parents "Virtual" functions are just instance variables