Typed stack allocation

Similar documents
Programming Languages

Typed Lambda Calculus and Exception Handling

Extracting the Range of cps from Affine Typing

CS 6110 S11 Lecture 25 Typed λ-calculus 6 April 2011

1 Introduction. 3 Syntax

Programming Languages Third Edition. Chapter 7 Basic Semantics

Lambda Calculus. Type Systems, Lectures 3. Jevgeni Kabanov Tartu,

CMSC 336: Type Systems for Programming Languages Lecture 5: Simply Typed Lambda Calculus Acar & Ahmed January 24, 2008

A Typed Lambda Calculus for Input Sanitation

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Simply-Typed Lambda Calculus

CSE505, Fall 2012, Midterm Examination October 30, 2012

Mutable References. Chapter 1

Programming Languages Lecture 15: Recursive Types & Subtyping

Compiler Construction

Programming Languages Lecture 14: Sum, Product, Recursive Types

CS558 Programming Languages

A Type System for Functional Traversal-Based Aspects

Concepts of programming languages

CS 6110 S11 Lecture 12 Naming and Scope 21 February 2011

Compiler Construction

Control Flow Analysis with SAT Solvers

Programming Languages Fall 2014

Types for References, Exceptions and Continuations. Review of Subtyping. Γ e:τ τ <:σ Γ e:σ. Annoucements. How s the midterm going?

CSE 505, Fall 2008, Midterm Examination 29 October Please do not turn the page until everyone is ready.

Programming Languages Third Edition. Chapter 10 Control II Procedures and Environments

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Optimizing Closures in O(0) time

Qualifying Exam in Programming Languages and Compilers

CSCI B522 Lecture 11 Naming and Scope 8 Oct, 2009

G Programming Languages - Fall 2012

Midterm 1. CMSC 430 Introduction to Compilers Spring Instructions Total 100. Name: March 14, 2012

Tradeoffs. CSE 505: Programming Languages. Lecture 15 Subtyping. Where shall we add useful completeness? Where shall we add completeness?

Featherweight Java (FJ)

1. Abstract syntax: deep structure and binding. 2. Static semantics: typing rules. 3. Dynamic semantics: execution rules.

The Typed λ Calculus and Type Inferencing in ML

CS558 Programming Languages

G Programming Languages - Fall 2012

Part VI. Imperative Functional Programming

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

Implementing functional languages with abstract machines

CMSC 330: Organization of Programming Languages. Operational Semantics

CS-XXX: Graduate Programming Languages. Lecture 9 Simply Typed Lambda Calculus. Dan Grossman 2012

CVO103: Programming Languages. Lecture 5 Design and Implementation of PLs (1) Expressions

Chapter 13: Reference. Why reference Typing Evaluation Store Typings Safety Notes

Hiding local state in direct style: a higher-order anti-frame rule

Semantics via Syntax. f (4) = if define f (x) =2 x + 55.

Lecture 13: Subtyping

A Type Theory for Memory Allocation and Data Layout (Extended Version)

The University of Nottingham SCHOOL OF COMPUTER SCIENCE A LEVEL 4 MODULE, SPRING SEMESTER MATHEMATICAL FOUNDATIONS OF PROGRAMMING ANSWERS

Where is ML type inference headed?

Lecture Notes: Control Flow Analysis for Functional Languages

Runtime. The optimized program is ready to run What sorts of facilities are available at runtime

An Operational and Axiomatic Semantics for Non-determinism and Sequence Points in C

Costly software bugs that could have been averted with type checking

MPRI course 2-4 Functional programming languages Exercises

From IMP to Java. Andreas Lochbihler. parts based on work by Gerwin Klein and Tobias Nipkow ETH Zurich

On Meaning Preservation of a Calculus of Records

Lambda Calculus: Implementation Techniques and a Proof. COS 441 Slides 15

CIS 500 Software Foundations Fall October 2

Structure of Programming Languages Lecture 10

Lecture Note: Types. 1 Introduction 2. 2 Simple Types 3. 3 Type Soundness 6. 4 Recursive Types Subtyping 17

A Sound Polymorphic Type System for a Dialect of C

COS 320. Compiling Techniques

Constrained Types and their Expressiveness

Lecture Notes on Alias Analysis

Run-Time Environments/Garbage Collection

Type Systems Winter Semester 2006

Theory and Implementation of a Functional Programming Language

Induction and Semantics in Dafny

More Lambda Calculus and Intro to Type Systems

Lecture Notes on Aggregate Data Structures

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

Chapter 5. Names, Bindings, and Scopes

Types and Programming Languages. Lecture 6. Normalization, references, and exceptions

Functions and Parameter Passing

Architecture of LISP Machines. Kshitij Sudan March 6, 2008

Sémantique des Langages de Programmation (SemLP) DM : Region Types

CS558 Programming Languages

11. a b c d e. 12. a b c d e. 13. a b c d e. 14. a b c d e. 15. a b c d e

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

Note that in this definition, n + m denotes the syntactic expression with three symbols n, +, and m, not to the number that is the sum of n and m.

More Lambda Calculus and Intro to Type Systems

Compile-Time Garbage Collection for Lazy Functional Languages

We defined congruence rules that determine the order of evaluation, using the following evaluation

CSc 520 final exam Wednesday 13 December 2000 TIME = 2 hours

Lecture 5: The Halting Problem. Michael Beeson

Topic 3: Propositions as types

Lambda Calculus and Type Inference

CMSC 330: Organization of Programming Languages. Lambda Calculus

Garbage Collection. Weiyuan Li

(Refer Slide Time: 4:00)

Lambda Calculus and Extensions as Foundation of Functional Programming

Heap, Variables, References, and Garbage. CS152. Chris Pollett. Oct. 13, 2008.

Lecture 9: Typed Lambda Calculus

Last class. CS Principles of Programming Languages. Introduction. Outline

Space-Efficient Blame Tracking for Gradual Types

Principles of Programming Languages Topic: Scope and Memory Professor Louis Steinberg Fall 2004

A Type System for Object Initialization In the Java TM Bytecode Language

CS558 Programming Languages

Transcription:

University of Colorado, Boulder CU Scholar Computer Science Undergraduate Contributions Computer Science Spring 5-1-2011 Typed stack allocation Brian Brooks University of Colorado Boulder Follow this and additional works at: https://scholar.colorado.edu/csci_ugrad Recommended Citation Brooks, Brian, "Typed stack allocation" (2011). Computer Science Undergraduate Contributions. 36. https://scholar.colorado.edu/csci_ugrad/36 This Thesis is brought to you for free and open access by Computer Science at CU Scholar. It has been accepted for inclusion in Computer Science Undergraduate Contributions by an authorized administrator of CU Scholar. For more information, please contact cuscholaradmin@colorado.edu.

Typed stack allocation Brian Brooks brian.brooks@colorado.edu 1 Introduction The verification of memory safety no program will crash when referencing memory falls into two categories. A runtime system may enforce memory safety at a cost. Or, we may rely on error-prone programmers. Runtime overhead, most noticeably garbage collection, is undesirable in embedded or real-time systems. The frequency of collection points is not deterministic. Languages that rely on garbage collection suffer from poor cache locality, occupy more memory than necessary, and usually spend more time copying data throughout memory hierarchy than performing meaningful computations. With enough memory, Appel [2] claims that it is more expensive to explicitly free memory than to leave it for a garbage collector. While garbage collection yields simpler and cleaner syntax, it is worth understanding the circumstances under which garbage collection can be cheaper than manually deallocating memory. The result of Appel s work states that garbage collection becomes less expensive when you have seven times as much memory as you have data within your program. Relying on programmers to safely and explicitly allocate, access, and deallocate memory has been the infamous source of unreliable software. There are many advantages to explicit memory management e.g. deallocating memory immediately after it s last access instead of waiting for a GC to reclaim it. However, this ad-hoc method of verification has proven over time that secure software systems require a machine to verify memory safety. Why is it that the most popular techniques for guaranteeing memory safety impose runtime overhead? applytwice :: (a -> a) -> a -> a applytwice f x = f (f x) applytwice takes two arguments: f :: (a -> a) and x :: a. When we apply applytwice to a function f, there is no guarantee that f takes exactly one parameter. We may end up with a partially applied function if f takes two or more parameters. Because f is unknown during compile-time we may allocate f in the heap. Higher-order languages tend to allocate most values in the heap. There has yet to be a silver-bullet method for statically determining optimal lifetimes of values. Thus, languages rely on garbage collection to periodically manage memory during program execution. 1.1 Contributions Our approach towards memory safety for free only permits values that may be allocated on the runtime stack. We do not rely on a garbage collector or runtime checks to guarantee memory safety. We define an abstract machine that can model the runtime stack during execution of programs. We then provide a type and effect system for describing memory-safe programs with respect to the abstract machine. 1

2 Modeling stack allocation In imperative languages such as C and C++, the lifetimes of local variables are controlled by the basic block that they are defined in. In the function, int f() { int a = 0; return 42; } the variable a will be allocated on the stack within f() s activation record. Once the body of f() is done evaluating, we return the value 42 and the activation record as well as a are popped off the stack. Since, we can statically determine a s lifetime, we may infer points of allocation and deallocation. As a property of memory safety, we must ensure that we do not access a before it has been allocated and after it has been deallocated. Compilers for type-unsafe languages allow programmers to write code that returns the address of a local variable. GCC 4.0.1 does not give a warning or error for the following function, int *x() { int a; int *b = &a; return b; } In the simply typed lambda calculus, the syntactic basic block is lambda abstraction: λx.e where x is input and e is output. Due to the operational semantics of the simply typed lambda calculus, x may live longer than the evaluation of the lambda abstraction that allocated its storage. Consider evaluation of this term: λx.λy.x 4 8 x will be bound to 4, y will be bound to 8, and we need to evaluate x which must exist in memory somewhere. Since the two lambda abstractions have already been pushed onto and popped off of the runtime stack in LIFO order x must be allocated in the heap. The behavior of a runtime stack is that parameter values are allocated upon function application and are deallocated when the function returns. Since we are only interested in stack allocation, we must be able to describe not only function application but also returning from functions in our operational semantics. 2.1 ECD machine Consider the syntax of the call-by-value λ-calculus with integers. Expressions are either integers, variables, abstractions, or applications: i P Integers x P V ariables e P Expressions ::= i x λx.e e e Expressions decompose into a context (C) and a redex (r). A context is simply an expression with a hole () which serves as a placeholder for a redex, i.e. e = C[r]. The following grammar defines contexts that preserve left-to-right evaluation of our calculus: C P Contexts ::= C e v C A redex, shorthand for reducible expression, is an expression that can take a step according to a reduction rule. A value (v) is either an integer or a closure: v P V alues ::= i xλx.e, ρy 2

Closures are abstractions whose free variables are bound in the environment (ρ). An environment is a set of bindings which map variables to values, e.g. tx ÞÑ vu. Environments are defined by the following grammar: ρ P Environments ::= H tx ÞÑ vu Z ρ We use Z to denote the union of two disjoint sets. Notice that this requires all variables to have unique names. An ECD machine state (S) is represented by a triple containing a control an expression, an environment, and a dump a call stack. The evaluation rules for the ECD machine are defined in Figure 2.1. (Var) handles variable lookup by extracting values out of the environment ρ. (Lam) creates a closure by duplicating ρ. (App) applies a closure to a value. We reinstate the closure s environment ρ 1 extending it with a new binding tx ÞÑ vu. Notice that control is transferred to e and the control and environment (C, ρ) are saved on the call stack using for concatenation. (Ret) returns control to a previous context. The context C and environment ρ 1 are popped off the call stack and reinstated in their respective places. Notice v is placed in the of C. (Var) xc[x], ρ, σy ÞÝÑ xc[ρ(x)], ρ, σy (Lam) xc[λx.e], ρ, σy ÞÝÑ xc[xλx.e, ρy], ρ, σy (App) xc[xλx.e, ρ 1 y v], ρ, σy ÞÝÑ xe, tx ÞÑ vu Z ρ 1, (C, ρ) σy (Ret) xv, ρ, (C, ρ 1 ) σy ÞÝÑ xc[v], ρ 1, σy Figure 1: ECD machine Evaluation of an expression is defined by a function: eval ECD (e) = (v, ρ) if xe, H, []y ÝÑ xv, ρ, []y The initial machine state contains an empty environment and call stack. If the machine converges after a series of finite steps, the result is (v, ρ). As an example, a trace of eval ECD (λx.λy.x 1 2) = (1, H) looks like: 2.2 ECDH machine x λx.λy.x 1 2, H, [] y x xλx.λy.x, Hy 1 2, H, [] y x λy.x, tx ÞÑ 1u, [( 2, H)] y x xλy.x, tx ÞÑ 1uy, tx ÞÑ 1u, [( 2, H)] y x xλy.x, tx ÞÑ 1uy 2, H, [] y x x, tx ÞÑ 1, y ÞÑ 2u, [(, H)] y x 1, tx ÞÑ 1, y ÞÑ 2u, [(, H)] y x 1, H, [] y In this section, we modify the ECD machine to expose the heap a run-time representation of memory. As a result, the evaluation rules allocate values in the heap and dereference pointers as needed. We define the heap (µ) as a set of bindings that map heap addresses (a) to values. Environment variables are modified to map to heap addresses. We let Dom(µ) refer to the heap addresses in µ, and Dom(ρ) refers to the variables in ρ. The semantics of the ECDH machine make allocation and dereferencing explicit. However, values are never deallocated. We can specify values that are no longer required for evaluation, Definition 2.1 (Garbage) If xe, tx ÞÑ au Z ρ, σ, ta ÞÑ vu Z µy ÞÝÑ S 1, then the binding tx ÞÑ au and its associated storage ta ÞÑ vu are garbage iff xe, ρ, σ, µy ÞÝÑ S 1. 3

(Var) xc[x], ρ, σ, µy ÞÝÑ xc[µ(ρ(x))], ρ, σ, µy x P Dom(ρ), ρ(x) P Dom(µ) (Lam) xc[λx.e], ρ, σ, µy ÞÝÑ xc[xλx.e, ρy], ρ, σ, µy (App) xc[xλx.e, ρ 1 y v], ρ, σ, µy ÞÝÑ xe, tx ÞÑ au Z ρ 1, (C, ρ) σ, ta ÞÑ vu Z µy a R Dom(µ) (Ret) xv, ρ, (C, ρ 1 ) σ, µy ÞÝÑ xc[v], ρ 1, σ, µy Figure 2: ECDH machine 2.3 ECDH machine The missing functionality of the ECDH machine is deallocation of values similar to popping a stack frame. The (Ret) rule is modified in the ECDH machine to reflect this. However, we must be sure to deallocate the same value that the lambda allocated. To keep track of the address, whenever we allocate a value and transfer control to the body of a lambda, we push the address on the dump. When we return, we retrieve the address to deallocate from the dump. (Var) xc[x], ρ, σ, µy ÞÝÑ xc[µ(ρ(x))], ρ, σ, µy x P Dom(ρ), ρ(x) P Dom(µ), µ(ρ(x)) (Lam) xc[λx.e], ρ, σ, µy ÞÝÑ xc[xλx.e, ρy], ρ, σ, µy (App) xc[xλx.e, ρ 1 y v], ρ, σ, µy ÞÝÑ xe, tx ÞÑ au Z ρ 1, (C, ρ, a) σ, ta ÞÑ vu Z µy a R Dom(µ) (Ret) xv, ρ, (C, ρ 1, a) σ, ta ÞÑ v 1 u Z µy ÞÝÑ xc[v], ρ 1, σ, ta ÞÑ u Z µy Figure 3: ECDH machine Evaluation is defined as, eval ECDHS (e) = (v, ρ, µ) if xe, H, [], Hy ÝÑ xv, ρ, [], µy Definition 2.2 A state S = xe, ρ, σ, µy is stuck if there does not exist another state S 1 such that S ÝÑ S 1 and e is not a value. 3 Typed stack allocation The judgement Γ $ t : ϕ τ may be read as Under the assumptions Γ, term t observes the effects ϕ and yields a value of type τ. An effect can be thought of as reading a value from a variable. Thus, the effect ϕ of an expression e may be though of as the set of variables and their corresponding values that may be accessed upon evaluating e. A key insight to this type system is that we annotate the function type with a set of effects: τ ϕ ÝÑ τ 4

This allows us to type functions with respect to the variables that they may access during evaluation. We define fv(τ) as a function that returns the set of free effects in the type τ. H denotes an empty set of effects. τ ::= int τ ϕ ÝÑ τ Γ $ e : ϕ τ Const (c) = τ Γ $ c : H τ Lam Γ, x : τ $ e : ϕ τ 1 x R fv(τ 1 ) Γ $ λx : τ.e : H τ ϕtxu ÝÝÝÝÑ τ 1 App Var x : τ P Γ Γ $ x : txu τ Γ $ e 1 : ϕ τ ϕ1 ÝÑ τ 1 Γ $ e 2 : ϕ2 τ Γ $ e 1 e 2 : ϕ Y ϕ1 Y ϕ 2 τ 1 Figure 4: λ S Typing The Const rule handles constants and we assume there is some function that maps constants to base types. Under the Var rule, we observe the effect x which yields the final effect type x τ. The Lam rule handles lambdas. They key idea here is that the variable x is not an observable effect within τ 1. Notice that x may be observable within ϕ though. App handles applications where the observable effects are gathered in the final effect type ϕ Y ϕ 1 Y ϕ 2 τ 1. 3.1 λ S Examples The type and effect system of λ S ensures that we will never reach a stuck state in the ECDH machine. This means that all well-typed λ S terms will allocate all values on the stack and evaluate to some value. Let us examine terms that may or may not classify as well-typed. The identity function λx : bool.x is well-typed and it is safe to deduce that x may be allocated on the stack because its only use occurs before the corresponding lambda returns. In fact, all terms of type τ Ñ τ may safely allocate their parameters on the stack. In λx : bool.w, x is never used. Thus, it is safe to allocated on the stack. Terms of the type τ 1 Ñ τ 2 Ñ τ n are a bit more interesting. The term λg : int.λy : int.x is well-typed, but λx : int.λy : int.x is not. In λg : int.λy : int.x, both g and y are never used; it is safe to allocate them on the stack. However, in λx : int.λy : int.x, x is used after the lambda that allocated x returns. Understand how we fail to construct a derivation for this term: x : int, y : int $ x : txu int Var x : int $ λy : int.x : H int txu ÝÝÑ int $ λx : int.λy : int.x :? Lam FAIL The reason why we cannot apply the last Lam rule is because x P fv(int txu ÝÝÑ int). This violates the constraint in Lam that is crucial for ensuring safe stack allocation of lambda 5

parameters. Function applications offer the most interesting derivations despite the simplicity of App. It may be obvious to notice that the term λx : int.(λy : int.y x) is well-typed and will evaluate properly in the ECDH machine. However, consider the faulty derivation of the term λx : int.(λy : int Ñ int.y λg : int.x): The derivation fails when trying to apply Lam because of the same reason in the previous failed derivation. In this example, the argument value λg : int.x applied to λy : int Ñ int.y is said to have escaped the application. Let us examine a case where arguments in an application do not escape. To make things simple, we are going to assume that a binding for w : int already exists in our typing assumptions Γ: Lam Var Γwxy $ w : twu int Γ wx $ λy : int Ñ int.w : H (int Ñ int) twu ÝÝÑ int Γ wx $ λy : int Ñ int.w λg : int.x : twu int Γ wxg $ x : txu int Var Γ wx $ λg : int.x : H int txu ÝÝÑ int Γ w $ λx : int.(λy : int Ñ int.w λg : int.x) : H int twu ÝÝÑ int Here we can see that effects from the non-escaping argument are not collected. 3.2 Soundness Type soundness states that a program will never enter a stuck state during execution. We attempt to prove type soundness in the style of Wright and Felleisen [8] utilizing the standard Progress and Preservation lemmas. The environment ρ and the heap µ must be consistent. That is, if we typecheck with respect to assumptions about the types of values in the heap, we must ensure that we evaluate with a heap that conforms to these assumptions. Γ $ ρ, µ Definition 3.1 A heap µ is said to be well typed with respect to a typing context Γ and environment ρ, written Γ $ ρ, µ, if for all x : τ P Γ, x P Dom(ρ) and ρ(x) P Dom(µ) and µ(ρ(x)) : τ. Intuitively, a heap µ is well typed if every value in the heap has the same type predicted by the assumptions in the typing context Γ. The traditional Progress lemma states that a well-typed term does not get stuck; either it is a value, or it can take a step according to the evaluation rules. For our purposes, we will rephrase Progress to mean that a well-typed state does not get stuck; either it contains a value, or it can take a step in evaluation. This means that we must define what it means for a state to be well typed. Figure 5 contains the typing judgements that describe what it means for a state to be well typed. We also require that the heap be well typed to rule out stuck states as being possible well typed states. Γ $ ρ, µ? Γ $ xe, ρ, σ, µy : τ Lam App Γ $ s : τ Lam Figure 5: λ S State Typing Lemma 3.2 (Progress) If $ s : τ where s = xe, ρ, σ, µy, then either s Ñ s 1 or e is a value and σ is empty. Proof. The proof proceeds by induction on the derivation of e : τ. 6

Const From the Const definition we have $ xc, ρ, σ, µy : τ. So either $ xc, [], σ, µy : τ if c is a value, or we may take a step in the form of xc, ρ, (C, ρ 1, a) σ, a µy ÞÝÑ xc[c], ρ 1, σ, ta ÞÑ u µy according to (Ret). Var Trivial since no variable is well-typed in an empty context. Lam App Preservation states that if a well-typed term takes a step in evaluation, then the resulting term is also well-typed. Lemma 3.3 (Preservation) If Γ $ xe, ρ, σ, µy : τ and xe, ρ, σ, µy Ñ xe 1, ρ 1, σ 1, µ 1 y, then Γ $ xe 1, ρ 1, σ 1, µ 1 y : τ. Definition 3.4 (Well-typed Contexts) A context C is well-typed, C : τ Ñ τ 1, if and only if e : τ and C[e] : τ 1. Lemma 3.5 (Unique Decomposition) If e : τ then either e is a value or there exists a context C and redex r such that e = C[r] and C : τ 1 Ñ τ and r : τ 1. Proof. The proof proceeds by induction on the derivation of e : τ. Const, Lam Trivial since e is a value. Var App Suppose e 1 and e 2 are values. Then let C = and r = e 1 e 2. So e 1 e 2 = C[r], C : ϕ τ 1 Ñ ϕ τ 1, and r : ϕ τ 1. Suppose e 1 is a value and e 2 is not a value. From the induction hypothesis there is a C 1 and r such that e 2 = C 1 [r], C 1 : τ 2 Ñ τ, r : τ 2, and r is a redex. Then C = e 1 C 1 so e = C[r] and C : τ 2 Ñ ϕ τ 1 Conjecture 3.6 (Type Soundness) If Γ $ s : τ where s = xe, ρ, σ, µy, then either s Ñ s 1 or e is a value of type τ and ρ, σ are empty. 4 Related Work Georgeff s [4] work has been noted to be the first in trying to determine stackability. The main contribution of his work is an extended SECD machine that allows partial application of abstractions. This is feasible by a closure of the form xλx.e, ρ l, ρ n y where ρ l is the localenvironment and ρ n is the non-local environment. Evaluation of nested lambda abstractions collect the bindings within the local-environment. An application of the form (e 1 e 2 ) proceeds if e 1 is closure where the body of the lambda abstraction is anything but a lambda abstraction. The local environment bindings are appended to the non-local environment as a whole upon function application. Stackability is retained for simple expressions that may have the type τ Ñ τ Ñ τ. Banerjee and Schmidt [3] build on Georgeff s work by noticing that stackability holds for expressions that may not classify as simple expressions. They observe that the essence 7

of stackability is that the shape of the environment must remain the same before and after execution of an expression. Specifically, stackability may be lost when the result of an application is a closure. Therefore, the environment trapped within the closure must be a subenvironment of the original environment. They then define the set of stackable expressions by examining dynamic semantic trees. This study yields a dynamic criterion that must hold for stackable expressions. Towards providing a static analysis to determine stackability, Banerjee and Schmidt then use a technique called closure analysis to determine what closures may be returned when evaluating an expression. They then modify the static analysis to ensure that dynamic criterion is held. Goldberg and Park [5] use an abstract interpretation-based escape analysis to determine stackability. Arguments may be stack allocated if they do not escape their function call. It is not yet clear to me what set of expressions they identify may retain stackability. Data-flow analysis refers to techniques that allow us to infer information about values such as points of allocation or access [1]. Unfortunately data-flow analysis depends on control-flow analysis which traces possible execution paths of a program. In functional programming languages, data-flow and control-flow analysis is difficult because they depend on each other[7][6]. 5 Conclusion We have defined an abstract machine that models stack allocation and specified a type and effect system for describing memory-safe programs with respect to the machine. 8

References [1] A.V. Aho, M.S. Lam, R. Sethi, and J.D. Ullman. Compilers: Principles, Techniques, & Tools. Addison-Wesley Publishing Company, USA, 2007. [2] Andrew W. Appel. Garbage collection can be faster than stack allocation. Inf. Process. Lett., 25(4):275 279, 1987. [3] Anindya Banerjee and David A. Schmidt. Stackability in the simply-typed, call-by-value lambda calculus. In IN PROCEEDINGS OF THE FIRST INTERNATIONAL STATIC ANALYSIS SYMPOSIUM, 1994. [4] Michael Georgeff. Transformations and reduction strategies for typed lambda expressions. ACM Trans. Program. Lang. Syst., 6(4):603 631, 1984. [5] B. Goldberg and Y. G. Park. Higher order escape analysis: optimizing stack allocation in functional program implementations. In Proceedings of the third European symposium on programming on ESOP 90, pages 152 160, New York, NY, USA, 1990. Springer-Verlag New York, Inc. [6] M. Might. Environment analysis of higher-order languages. PhD thesis, Georgia Institute of Technology, 2007. [7] O. Shivers. Control-Flow Analysis of Higher-Order Languages. PhD thesis, Carnegie Mellon University, 1991. [8] Andrew K. Wright and Matthias Felleisen. A syntactic approach to type soundness. Inf. Comput., 115(1):38 94, 1994. 9