Skip to content

Crash caused by using vargv, closure.acall and generators #318

Description

@Patrix9999

Hi!

I've been playing around lately with Squirrel, and tried to write a custom Behaviour Tree implementation when i've stumbled upon the language crash.
It's most likely occuring only when we use closure.acall with vargv and resume the generator.

I've tried to debug it myself (and still trying) but unfortunately i wasn't able to narrow down the root cause of this issue.
Here's the reproduction code:

BT <- {}

class BT.NodeState
{
    RUNNING = 0
    SUCCESS = 1
    FAILURE = 2
}

class BT.Node
{
    state = BT.NodeState.RUNNING
    children = null

    constructor(...)
    {
        this.children = vargv
    }

    function evaluate(...)
    {
        throw "Not implemented"
    }

	_result = null
    function _evaluate(vargv)
    {
        vargv.insert(0, this)

		 if (_result == null)
            _result = evaluate.acall(vargv)

		if (type(_result) == "generator")
		{
			local state = resume _result
			if (_result.getstatus() == "dead")
            	_result = null

			return state
		}

		local state = _result
    	_result = null

		return state
    }
}

class BT.Selector extends BT.Node
{
    function evaluate(...)
    {
        foreach (node in children)
        {
            state = node._evaluate(vargv)
            switch (state)
            {
                case BT.NodeState.SUCCESS:
                    return state

                case BT.NodeState.RUNNING:
                    do
                    {
                        yield state
                        state = node._evaluate(vargv)
                    } while (state == BT.NodeState.RUNNING)
            }
        }

        return state
    }
}

class BT.Tree extends BT.Node
{
    constructor(root_node)
    {
        base.constructor(root_node)
    }

    function evaluate(...)
    {
        local root_node = children[0]
        return root_node._evaluate(vargv)
    }

    function tick(...)
    {
        local root_node = children[0]
        local result = root_node._evaluate(vargv)

        return result
    }
}


local ai = BT.Tree(
    BT.Selector(
        BT.Selector(
        )
    )
)

local memory = {persistent = {}, volatile = {}}
ai.tick(-1, memory)

After first invocation of the ai.tick, the crash will occur, removing either generator from BT.Node or vargv passing to a evaluate method solves the problem, but this doesn't satisfy my needs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions