ialex32x / unity-jsb

It brings Javascript runtime capability to Unity3D by integrating QuickJS.
MIT License
337 stars 41 forks source link

Crash When Disposing ScriptPromise instance. #45

Open jo32 opened 3 years ago

jo32 commented 3 years ago

I wrote some code like:

var promise = new TypedScriptPromise<JSValue>(sc);
System.Action<object> callback = (object o) => {
    promise.Resolve(JSApi.JS_NULL);
};

and it crashed on this line: https://github.com/ialex32x/unity-jsb/blob/master/Assets/jsb/Source/ScriptRuntime.cs#L611

ialex32x commented 3 years ago

Hi jo32, can you give more detail about the crash? I can't reproduce it in my environment. BTW, the generic parameter T of TypedScriptPromise<> is expected as a C# type. If there is no need to return anything back to js, use AnyScriptPromise.

(I added a test in Assets/Examples/Source/SampleBehaviour.cs: AnotherWait())


    public AnyScriptPromise AnotherWait(ScriptContext ctx, int t)
    {
        var p = new AnyScriptPromise(ctx);
        StartCoroutine(_WaitForResolve(() => p.Resolve()));
        return p;
    }

    private System.Collections.IEnumerator _WaitForResolve(System.Action p)
    {
        yield return new WaitForSeconds(3f);
        p();
    }
jo32 commented 3 years ago

Sorry for not able providing enough example for you, I am able to solve this problem by removing one line in ScriptPromise.cs:

        protected virtual void Dispose(bool bManaged)
        {
            if (_context != null)
            {
                var context = _context;
                _context = null;
                // TODO: find out why the following two lines solve the crash problem
                context.FreeValue(_promise);
                // context.FreeValues(_resolving_funcs);
                _resolving_funcs = null;
                _promise = JSApi.JS_UNDEFINED;
            }
        }
ialex32x commented 3 years ago

Hi jo32, which commit are you currently using? It looks different from my version?


        protected virtual void Dispose(bool bManaged)
        {
            if (_context != null)
            {
                var context = _context;
                _context = null;
                context.FreeValues(_resolving_funcs);
                _resolving_funcs = null;
                context.GetRuntime().FreeScriptPromise(_promise);
                _promise = JSApi.JS_UNDEFINED;
            }
        }