wren-lang / wren

The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.
http://wren.io
MIT License
6.9k stars 552 forks source link

Request/Feature: tell WrenForeignClassMethods.allocate() what class is being allocated #959

Open cxw42 opened 3 years ago

cxw42 commented 3 years ago

(Moving discussion from https://github.com/wren-lang/wren/issues/498#issuecomment-808826754)

I am working on Vala bindings for Wren. Unless I am missing something, the allocate function receives no information identifying the class. Therefore, each class needs its own allocate() --- and thus each class must have a unique C callsite. Callsites are hard to create dynamically in compiled languages :) . My current workaround is a fixed list of stub functions I dynamically assign to Wren classes --- functional, but very repetitive and ugly (here et seq.).

If classes had type tags, I could use one allocate() in Vala, and switch on the type tag to determine what type to create. E.g.:

void generic_allocate(WrenVM vm) {
    var typetag = wrenGetTypeTagForSlot(vm, 0);
    Object *instance;
    switch(typetag) {
        case SOMETYPE: instance = new SomeType();
        ...
    }
    var ppObject = wrenSetSlotNewForeign(0,0,sizeof(Object*));
    *ppObject = instance;
}

At https://github.com/cxw42/wren/commit/d535f1629be231846186d0e4363109f4a00d5000 , I have a proof of concept that does not use type tags. Instead, it passes userData from WrenForeignClassMethods to allocate(). That commit relies on #942, but I could split this one off without too much trouble. Let me know what you think!

mhermier commented 3 years ago

I think, it should have a private data pointer/uintptr_t instead. I'm not sure but probably ideally it would reside in Obj but it would be a huge waste of memory...