Presentation is loading. Please wait.

Presentation is loading. Please wait.

Closure Compiler Baojian Hua Closure An implementation technique traditionally for functional languages Lisp, Scheme, Haskell, Ocaml,

Similar presentations


Presentation on theme: "Closure Compiler Baojian Hua Closure An implementation technique traditionally for functional languages Lisp, Scheme, Haskell, Ocaml,"— Presentation transcript:

1 Closure Compiler Baojian Hua bjhua@ustc.edu.cn

2 Closure An implementation technique traditionally for functional languages Lisp, Scheme, Haskell, Ocaml, F#, … But more popular in other (even OO) languages C++ 0x11, Lambda C# 3.5 Java 8.0 (this June?)

3 Call Stack LIFO discipline to support (recursive) function call Function frame also obeys LIFO, so most (C) compilers use call stack to hold frames frame 0 high address %ebp frame 1 frame 2 %esp low address

4 C-style Stack Frame int f (int arg0, int arg1, …) { int local1; int local2; …; } … arg1 arg0 ret addr old ebp local1 local2 … %ebp %esp

5 Higher-order functions Functions as values (first-class) Pass as arguments Return as values Stored into data structures Implementation: A code pointer, (i.e., a code heap address)

6 Nested functions int f(){ int x; int y; g(); return 0; } int g (){ int z; return z+x; } int f(){ int x; int y; g(); return 0; } Escaped variable We say function f is declared at level 0, and g is at level 1. General principal to compile nested functions: flatten! int g (){ int z; return z+x; } Ooops, where to find “ x ” ? But “ x ” is still in “ f ”’ s frame, right?

7 Static Links frame 0 xyxy Link z low address int f(){ int x; int y; g(%ebp); return 0; } int g (Link){ int z; return z+ link->x; } f g

8 Higher-order Nested Functions void->int f(){ int x; int y; return g; } h = f(); // h==g h(); // g() int g (){ int z; return z+x; } frame 0 xyxy f z g Function frames don ’ t obey LIFO discipline any more. What one need to do is to we need to keep frames live long enough! Heap-allocation!

9 Heap-allocated Frames void->int f(){ int x; int y; return g; } h = f(); // h == cg h(); int g (){ int z; return z+x; } frame 0 ret ebp frame next x y envcode f g cg

10 Heap-allocated Frames void->int f(){ int x; int y; return g; } h = f(); // h == cg h(); int g (){ int z; return z+x; } frame 0 env ebp frame next x y envcode g g cg h->code(h->env);

11 Closure Conversion By heap allocating function frame, inner function can visit variable in outer function, even if the outer function has returned relying on the GC to reclaim frames We can also make the closure explicit at source-level this is called closure conversion

12 Closure Conversion void->int f(){ int x; int y; int g(struct f_fr *env){ int z; return z+(env->x); } struct f_fr *env = malloc (link, x, y); return malloc(env, g); } frame 0 link x y envcode f g struct f_fr{ … *link; int x; int y; }; Closures are objects! Objects are closures!

13 From Closure to Inner Class void->int f(){ int x; int y; int g(){ int z; return z+x; } return g; } h = f(); h(); class f{ int x; int y; class g(){ int z; int foo(){ return z+x; } int foo(){ return new g(); } h = new f().foo(); h.foo();

14 From Closure to Inner Class class f{ int x; int y; class g(){ int z; int foo(){ return z+x; } int foo(){ return new g(); } h = new f().foo(); h.foo(); vptr x outer z h y f_foo vptr g_foo

15 Method Local Inner Class class A{ int x; int f(){ int y; class B{ int g(){ return x+y; } return new B(); } To access “ y ” in the method “ g ”, y must be heap-allocated (notice y is a method local variable for method f). But this violates the JVM semantics, so the Java designer invents the ugly “ final ” rule …


Download ppt "Closure Compiler Baojian Hua Closure An implementation technique traditionally for functional languages Lisp, Scheme, Haskell, Ocaml,"

Similar presentations


Ads by Google