tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Local procedures


From: Rob Landley
Subject: Re: [Tinycc-devel] Local procedures
Date: Wed, 12 Sep 2007 20:10:28 -0500
User-agent: KMail/1.9.6

On Wednesday 12 September 2007 5:54:16 am Zdenek Pavlas wrote:
> Antti-Juhani Kaijanaho wrote:
> > You only need the trampoline if you cannot make the function pointer fat
> > (ie. if you need to be binary compatible with vanilla C compilers).
> > Which, of course, describes tcc's situation fairly well.
>
> Even if you really need a trampoline, you don't need a fancy compiler
> for that.  It's easy to implement (at least on i386) using the existing
> support for attribute(regparm).  Real closures in C- way more fun than
> gcc's nested functions, which are quite limited and (rightfully, IMO)
> seldom used.
>
> #include <stdio.h>
> #include <malloc.h>
> #include <sys/mman.h>
>
> void* closure(void *code, void *data) {
>     char *c = malloc(10);
>     c[0] = 0xb8, *(int*)(c + 1) = (int)data; // mov eax, ...
>     c[5] = 0xe9, *(int*)(c + 6) = (char*)code - c - 10; // jmp ...
>     mprotect((void*)((int)c & ~0xfff), 1, PROT_READ|PROT_WRITE|PROT_EXEC);
>     return c;
> }

You assume that c[0] and c[5] are on the same page.

(And please put a ; in there instead of a comma, it took me three times longer 
than it should have to figure out what you're doing. :)

> void __attribute__((regparm(1))) /* expect arg #1 in eax */
> add_to(int *data, int i) {
>     *data += i;
> }
>
> int main() {
>     int sum = 0, i;
>     void (*fun)(int) = closure(add_to, &sum);
>     for (i = 0; i < 10; i++) fun(i);
>     free(fun);
>     printf("%d\n", sum);
> }

Ok, the question here is _why_ would you want to do that? :)

Rob
-- 
"One of my most productive days was throwing away 1000 lines of code."
  - Ken Thompson.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]