Breaking change in 5.8.x


#1

Hi,
I have a test Chai project that I play with - based on the code
http://pooperpig.com/?p=145
Nothing clever - it just registers a class with a then calls a script function which calls a method on that class.

It all works fine with 5.7.1

But crashes in 5.8.x (I’ve tried 5.8.0 and 5.8.1)

I get an error
Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const
{
try {
return eval_internal(t_e);
} catch (exception::eval_error &ee) {
ee.call_stack.push_back(shared_from_this());
throw;
}
}

In chaiscript_common.cpp
and see
libc++abi.dylib: terminating with uncaught exception of type chaiscript::exception::eval_error: Error: “Can not find object: Factory”

in the output (Factory is one of the objects passed to chaiscript, and the script calls methods of that object.

The error occurs when the script itself is called

    if (setUpLevel_script == NULL)
    {
        setUpLevel_script = chai.eval<std::function<void (int)>>("setUpLevel");
    }
    setUpLevel_script(levelNumber);

and the Factory is created with

// Get a reference to the Chaiscript Engine
auto chaiscript = CocosChai::create_chaiscript();

    // Instantiate our factory
    auto factory  = new EntityFactory();
    
    // tell ChaisCript about our factory
    chaiscript->add(chaiscript::var(factory), "Factory");

As I mentioned - this works with 5.7.1 - so any suggestions as to what might be causing it to fail in 5.8.x?


#2

I believe you were previously exploiting a bug where local variables could leak into function calls (functions should only ever have access to globals and the parameters passed into them).

You should be able to get it working again by explicitly making your factory a global:

chaiscript->add_global(chaiscript::var(factory), "Factory");

#3

Argh! Thank you! I think I just assumed that chai->add() was global!

This raises the question in my understanding, in this context, what does ‘local’ mean? What is the scope when I use ‘add’ rather than ‘add_global’?


#4

Great question.

When you add something here:

chai.add(var(i), "i");

It’s added at what might be called the “top level scope.” It’s not global, and it’s not local to a function. This decision was made to make things like:

chai.add(var(i), "i");
chai.eval("++i");

Work, and make sense. This also make the chai command line tool work a bit more naturally, since you can create variables and manipulate them.

-Jason


#5

OK - thanks for the explanation.

So - to make sure I have this clear in my head.

If I do the
chai.add(var(i), "i");

and then execute a simple eval , the eval can see the i variable in its scope.
But
if I execute a function, the function will not see the i

So whenever I want to access something (an object in my case) within a function in chaiScript, I need to either add the object globally, or pass it to the function as a parameter?

That seems to make sense!

Thanks.

Oh, and thanks for Chaiscript itself, too. I"m struggling, as a user, but I"m slowly getting there!


#6

Yes, 100% correct. Let me know if you have any other questions.