[LLVMdev] Closures, newbie question

David Given dg at cowlark.com
Sat Jan 26 14:37:12 PST 2013

On 26/01/13 20:03, David Given wrote:
> There are numerous ways to pass the stack frames into the inner
> functions. The naive approach is to simply have each stack frame contain
> a pointer to the enclosing frame, but that means that level4 has to
> evaluate f.level3.level2.level1.i. Optimising this is easy, and that's
> what I've done in the past, but I'm actually wondering whether it may
> not be easiest just to pass each frame in as a separate parameter and
> then let LLVM take care of the details:

I am reminded that in an implementation such as this, closures are *not*
first-class values --- you can't pass them around and they can only be
called statically. D'oh.

In order to produce first-class closures you need to bake all the
information described above statically into an object, and then pass
that object around.

My original implementation of this did this by having a special
pointer-to-closure representation which was two pointers; one to the
code, and one to the stack frame needed to call the code. An equally
valid alternative is to allocate a heap object with the same information
in it. In this case you're basically creating a object with a virtual
method; calling the method calls the closure.

There is another aspect to be wary of: depending on your implementation,
it's possible for two different closures of compatible types have
different calling conventions. Therefore anyone who has a simple
pointer-to-closure object doesn't know how to call the object. e.g.:

function level1()
  var i;
  function level2()
    return i;

From the point of view of the language, level1 and level2 have the same
type signature --- but as level2 is taking a hidden pointer to level1's
stack frame, and level1 doesn't, it's possible that the implementations

The easiest way around this is to arrange your implementation so that
the two functions above *do* have the same calling convention which can
be determined from the type signature. This requires a fixed number of
hidden parameters (usually one). The
multiple-stack-frames-passed-as-parameters implementation I described
above isn't suitable here, so I can't recommend it.

(My compiler could tell statically whether you were calling the closure
directly or via a pointer, and so would generate different code. This
made static calls much more efficient but it made calls via a pointer
less efficient, and I'm not sure whether it was worth it or not. It was
certainly much more complex.)

┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│ "Of course, on a sufficiently small planet, 40 km/hr is, in fact,
│ sufficient to punt the elastic spherical cow into low orbit." ---
│ Brooks Moses on r.a.sf.c

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130126/9439fc6b/attachment.sig>

More information about the llvm-dev mailing list