Skip to content

Calling wren method handle from inside a bound foreign method body #1169

Open
@ConorDamery

Description

@ConorDamery

Let say that I have these two wren classes:

foreign class Item {
    construct new() { }
}

class Builder {
    foreign static create(type)
}

Somewhere in the main module I'm calling Builder.create(Item).
And let say that Builder.create is bound to this method:

static void Create(WrenVM* vm)
{
    wrenEnsureSlots(vm, 2); // There should be 2 slots (0 for caller and 1 for the argument)
    WrenHandle* classHandle = wrenGetSlotHandle(vm, 1); // Get the class type from arg 1 (Item)
    WrenHandle* constructorHandle = wrenMakeCallHandle(vm, "new()"); // Make constructor method handle

    wrenSetSlotHandle(vm, 0, classHandle); // Set class handle into slot 0 to call constructor on it
    WrenInterpretResult res = wrenCall(vm, constructorHandle); // Assume checking result
    void* data = wrenGetSlotForeign(vm, 0); // Get return in slot 0, proceed with casting/use

    // Clean up ...
}

The idea behind this is that the Builder.create function will construct the class that is passed in it's argument with a new() call, and return the new variable with some processing on the host side.

The problem is that even tho I've verified the class handle to be of type 'Item metaclass', when calling wrenCall the following line of code vm->apiStack = NULL; will remove the handle from the stack. Since wrenSetSlotHandle internally calls vm->apiStack[slot] = value; And will cause the app to crash as it's trying to call a function from a different class, in this case, the class that originally called Builder.create which happens to be called 'Game'.

Is this intended behaviour? And if so, then how can I achieve the functionality I need?
Note that if I change the create function to simple do this on wren side it works as expected (but without the host processing):

class Builder {
    static create(type) {
        return type.new()
    }
}

So it should in theory be possible to do this on the host side.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions