matusnovak / wrenbind17

A header only library for binding C++17 classes and functions to Wren, an embeddable programming language
https://matusnovak.github.io/wrenbind17
MIT License
65 stars 10 forks source link

calling method with std::list throws assertion error #8

Open klvnptr opened 2 years ago

klvnptr commented 2 years ago

I have the following Wren code in "main.wren"

class MyClass {
    construct new() { }

    flyTo(city) {
        System.print("Flying to %(city)")
    }

    flyToList(cities) {
        System.print("flyToList.count %(cities.count)")

        cities.each { |word|
            System.print("Flying to %(word) FF")
        }
    }
}

var t = MyClass.new()

And I have the following C++ code:

int main()
{
    const char *module = "main";
    std::string src = read_main("src/main.wren");

    wren::VM vm;

    vm.runFromSource(module, src);

    std::list<int> ml;
    ml.push_back(2);

    wren::Method listCall = vm.find(module, "t").func("flyToList(_)");
    listCall(ml);

    return 0;
}

Running the C++ code throws the following error:

[../wren/src/vm/wren_vm.c:1658] Assert failed in validateApiSlot(): Not that many slots.

If I remove the ml.push_back(2); line, than everything is okay:

flyToList.count 0

What am I getting wrong? Thank you.

matusnovak commented 2 years ago

Hi @klvnptr

I apologize for a late reply. I can't reproduce your problem. I have used the following code, based on yours, added into the existing test suite:

// In file: tests/lists.cpp

TEST_CASE("Pass list of integers") {
    const std::string code = R"(
        class MyClass {
            construct new() { }

            flyTo(city) {
                System.print("Flying to %(city) ")
            }

            flyToList(cities) {
                System.print("flyToList.count %(cities.count) ")

                cities.each { |word|
                               System.print("Flying to %(word) FF")
                }
            }
        }

        var t = MyClass.new()
    )";

    wren::VM vm;

    vm.runFromSource("main", code);
    auto func = vm.find("main", "t").func("flyToList(_)");

    std::list<int> ml;
    ml.push_back(2);

    auto res = func(ml);
}

And it prints:

C:\Projects\wrenbind17\cmake-build-debug\WrenBind17_Tests.exe -r xml -d yes --order lex "Pass list of integers"
Testing started at 14:58 ...
flyToList.count 1 
Flying to 2 FF
Process finished with exit code 0

I have tested this with Clang on Windows (version Clang 11.0.0 with MSVC-like command-line) and also with MSVC (version MSVC 19.28.29914.0). Both work.

I am building it with cmake [...] -DWRENBIND17_BUILD_WREN=ON -DWRENBIND17_BUILD_TESTS=ON. So that the Wren is built from the git submodules, not an external library.

For the reference, the Wren git submodule (wrenbind17/libs/wren) has the following latest commit on my development machine where I run the tests:

commit 77079f2f4925b32de7c6647a88f3860e1b0eae2f (HEAD, origin/main, origin/HEAD)
Author: ruby0x1 <ruby0x1@pm.me>
Date:   Sun Nov 14 01:00:19 2021 -0800

    CI: artifacts

Perhaps your version of Wren you are using is at much older version? Also, what compiler and OS are you using?