On May 28, 2013, at 20:38 , Marvin Humphrey <[email protected]> wrote:

> Last, find a way to persuade the dynamic loader to resolve all method
> invocation functions at a given offset to a single compiled thunk,
> **regardless of the method signature**.

Here's an interesting blog post discussing this topic:

    http://blog.omega-prime.co.uk/?p=121

The program below works for me on OS X when compiled with

    cc -O2 -Wl,-alias,_thunk1,_Obj_Add,-alias,_thunk2,_Obj_Sub alias.c -o alias

But the thunks should actually be written in assembler, so we don't have to 
rely on compiler optimizations.

A single thunk per offset might be bad for branch prediction. But this could be 
worked around by providing separate thunks for each method.

Nick


#include <stdio.h>
#include <stdlib.h>

typedef struct VTable VTable;

typedef struct Obj {
    VTable *vtable;
    int value;
} Obj;

typedef void
(*method_t)(Obj* self);

struct VTable {
    method_t method1;
    method_t method2;
};

void
thunk1(Obj *self) {
    self->vtable->method1(self);
}

void
thunk2(Obj *self) {
    self->vtable->method2(self);
}

Obj_add(Obj *self, int value) {
    self->value += value;
}

void
Obj_sub(Obj *self, int value) {
    self->value -= value;
}

VTable vtable = {
    (method_t)Obj_add,
    (method_t)Obj_sub
};

Obj*
Obj_new(int value) {
    Obj *self = (Obj*)malloc(sizeof(Obj));
    self->vtable = &vtable;
    self->value  = value;
    return self;
}

int
Obj_Add(Obj *self, int value);

int
Obj_Sub(Obj *self, int value);

int
main() {
    Obj *obj = Obj_new(42);
    Obj_Add(obj, 10);
    Obj_Sub(obj, 5);
    printf("%d\n", obj->value);
    return 0;
}

Reply via email to