Example #1
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            if (DuktapeDLL.duk_is_object(ctx, idx) ||/* && check if js delegate type (hidden property) */
                DuktapeDLL.duk_is_function(ctx, idx))
            {
                var             heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                var             cache   = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetDelegate(heapptr, out fn))
                {
                    // Debug.LogWarningFormat("cache hit {0}", heapptr);
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx));
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                // Debug.LogWarningFormat("cache create : {0}", heapptr);
                cache.AddDelegate(heapptr, fn);
                return(true);
            }
            o = null;
            return(false);
        }
Example #2
0
        private static int _GetTimerFunction(IntPtr ctx, out DuktapeFunction fn)
        {
            if (!DuktapeDLL.duk_is_function(ctx, 0))
            {
                fn = null;
                return(0);
            }
            if (!DuktapeDLL.duk_is_number(ctx, 1))
            {
                fn = null;
                return(1);
            }
            var top_index = DuktapeDLL.duk_get_top_index(ctx);

            // Debug.Log($"_GetTimerFunction {top} ?? {DuktapeDLL.duk_get_top(ctx)}");
            DuktapeValue[] argv = null;
            if (top_index > 1)
            {
                argv = new DuktapeValue[top_index - 1];
                for (var i = 2; i <= top_index; i++)
                {
                    DuktapeDLL.duk_dup(ctx, i);
                    var argPtr = DuktapeDLL.duk_get_heapptr(ctx, -1);
                    argv[i - 2] = new DuktapeValue(ctx, DuktapeDLL.duk_unity_ref(ctx), argPtr);
                }
            }
            DuktapeDLL.duk_dup(ctx, 0);
            var fnPtr = DuktapeDLL.duk_get_heapptr(ctx, -1);

            fn = new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx), fnPtr, argv);
            return(-1);
        }
Example #3
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            //TODO: 20200320 !!! 如果 o 不是 jsobject, 且是 Delegate 但不是 DuktapeDelegate, 则 ... 处理

            if (DuktapeDLL.duk_is_object(ctx, idx) || DuktapeDLL.duk_is_function(ctx, idx))
            {
                var             heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                var             cache   = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetDelegate(heapptr, out fn))
                {
                    // Debug.LogWarningFormat("cache hit {0}", heapptr);
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx), heapptr);
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                // Debug.LogWarningFormat("cache create : {0}", heapptr);
                cache.AddDelegate(heapptr, fn);
                return(true);
            }
            // else if (DuktapeDLL.duk_is_object(ctx, idx))
            // {
            //     return duk_get_classvalue<T>(ctx, idx, out o);
            // }
            o = null;
            return(false);
        }
Example #4
0
        public static bool duk_get_delegate <T>(IntPtr ctx, int idx, out T o)
            where T : class
        {
            if (DuktapeDLL.duk_is_object(ctx, idx) ||/* && check if js delegate type (hidden property) */
                DuktapeDLL.duk_is_function(ctx, idx))
            {
                DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE_WEAK);
                var refid = DuktapeDLL.duk_get_int(ctx, -1);
                DuktapeDLL.duk_pop(ctx);

                var             cache = DuktapeVM.GetObjectCache(ctx);
                DuktapeDelegate fn;
                if (cache.TryGetTypedWeakObject(refid, out fn) && fn != null)
                {
                    o = fn.target as T;
                    return(true);
                }
                // 默认赋值操作
                DuktapeDLL.duk_dup(ctx, idx);
                var heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx);
                fn = new DuktapeDelegate(ctx, DuktapeDLL.duk_unity_ref(ctx));
                var vm = DuktapeVM.GetVM(ctx);
                o = vm.CreateDelegate(typeof(T), fn) as T;

                // DuktapeDelegate 拥有 js 对象的强引用, 此 js 对象无法释放 cache 中的 object, 所以这里用弱引用注册
                // 会出现的问题是, 如果 c# 没有对 DuktapeDelegate 的强引用, 那么反复 get_delegate 会重复创建 DuktapeDelegate
                refid = cache.AddWeakObject(fn);
                DuktapeDLL.duk_unity_set_prop_i(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE_WEAK, refid);
                cache.AddJSValue(o, heapptr);
                return(true);
            }
            o = null;
            return(false);
        }
Example #5
0
        private static void replace_by_builtin(IntPtr ctx, string t, uint k)
        {
            DuktapeDLL.duk_builtins_reg_get(ctx, k);    // c
            DuktapeDLL.duk_get_prop_string(ctx, -2, t); // cs

            // copy static fields from c# to c
            DuktapeDLL.duk_enum(ctx, -1, 0);
            while (DuktapeDLL.duk_next(ctx, -1, true))
            {
                DuktapeDLL.duk_dup(ctx, -2);
                if (!DuktapeDLL.duk_has_prop(ctx, -6))
                {
                    DuktapeDLL.duk_put_prop(ctx, -5);
                }
                else
                {
                    DuktapeDLL.duk_pop_2(ctx); // pop key and value
                }
            }
            DuktapeDLL.duk_pop(ctx);                              // pop enum

            DuktapeDLL.duk_get_prop_string(ctx, -2, "prototype"); // c  prototype
            DuktapeDLL.duk_get_prop_string(ctx, -2, "prototype"); // cs prototype   <stack> [c, cs, c.prototype, cs.prototype]

            DuktapeDLL.duk_set_prototype(ctx, -2);                // c.prototype = cs.prototype   <stack> [c, cs, c.prototype]
            DuktapeDLL.duk_pop(ctx);                              // pop c.prototype
            DuktapeDLL.duk_put_prop_string(ctx, -2, "_raw");      // cs._raw = c
            DuktapeDLL.duk_put_prop_string(ctx, -2, t);           // <global>
        }
Example #6
0
 protected static void duk_begin_object(IntPtr ctx, string objectname, Type type)
 {
     DuktapeDLL.duk_push_object(ctx);
     DuktapeDLL.duk_dup(ctx, -1);
     // DuktapeDLL.duk_dup(ctx, -1);
     // DuktapeVM.GetVM(ctx).AddExported(type, new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx)));
     DuktapeDLL.duk_put_prop_string(ctx, -2, objectname);
 }
Example #7
0
        protected static void duk_begin_special(IntPtr ctx, string name)
        {
            DuktapeDLL.duk_push_c_function(ctx, object_private_ctor, 0); // ctor
            DuktapeDLL.duk_dup(ctx, -1);
            DuktapeDLL.duk_dup(ctx, -1);
            var typeValue = new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx)); // ctor, ctor

            DuktapeVM.GetVM(ctx).AddSpecial(name, typeValue);
            DuktapeDLL.duk_put_prop_string(ctx, -3, name);        // ctor
            DuktapeDLL.duk_push_object(ctx);                      // ctor, prototype
            DuktapeDLL.duk_dup_top(ctx);                          // ctor, prototype, prototype
            DuktapeDLL.duk_put_prop_string(ctx, -3, "prototype"); // ctor, prototype
        }
Example #8
0
        public DuktapeThread(DuktapeFunction fn)
        {
            var ctx = fn.ctx;
            var vm  = DuktapeVM.GetContext(ctx).vm;
            var idx = DuktapeDLL.duk_push_thread(ctx);

            DuktapeDLL.duk_dup(ctx, -1);
            var ptr = DuktapeDLL.duk_get_heapptr(ctx, -1);

            _thread        = new DuktapeValue(ctx, DuktapeDLL.duk_unity_ref(ctx), ptr);
            _threadContext = new DuktapeContext(vm, DuktapeDLL.duk_get_context(ctx, idx));
            if (fn.Push(_threadContext.rawValue))
            {
            }

            DuktapeDLL.duk_pop(ctx);
        }
Example #9
0
        protected static void duk_begin_class(IntPtr ctx, string typename, Type type, DuktapeDLL.duk_c_function ctor)
        {
            // Debug.LogFormat("begin class {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_push_c_function(ctx, ctor, DuktapeDLL.DUK_VARARGS); // [ctor]
            DuktapeDLL.duk_dup(ctx, -1);
            // Debug.LogFormat("begin check {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_dup(ctx, -1);
            var refid = DuktapeVM.GetVM(ctx).AddExported(type, new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx)));

            DuktapeDLL.duk_push_uint(ctx, refid);
            DuktapeDLL.duk_put_prop_string(ctx, -3, DuktapeVM.OBJ_PROP_EXPORTED_REFID);
            // Debug.LogFormat("end check {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_put_prop_string(ctx, -3, typename);
            DuktapeDLL.duk_push_object(ctx);                      // [ctor, prototype]
            DuktapeDLL.duk_dup_top(ctx);                          // [ctor, prototype, prototype]
            DuktapeDLL.duk_push_c_function(ctx, object_dtor, 1);
            DuktapeDLL.duk_set_finalizer(ctx, -3);                // set prototype finalizer
            DuktapeDLL.duk_put_prop_string(ctx, -3, "prototype"); // [ctor, prototype]
        }
Example #10
0
        protected static void duk_begin_class(IntPtr ctx, string typename, Type type, DuktapeDLL.duk_c_function ctor)
        {
            // Debug.LogFormat("begin class {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_push_c_function(ctx, ctor, DuktapeDLL.DUK_VARARGS); // [ctor]
            DuktapeDLL.duk_dup(ctx, -1);                                       // [ctor ctor]
            // Debug.LogFormat("begin check {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_dup(ctx, -1);                                       // [ctor ctor ctor]
            var ptr    = DuktapeDLL.duk_get_heapptr(ctx, -1);
            var typeid = DuktapeVM.GetVM(ctx).AddExportedType(type, new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx), ptr));

            DuktapeDLL.duk_unity_set_type_refid(ctx, -1, typeid); // constructor_function.!type == typeid
            // Debug.LogFormat("end check {0}", DuktapeDLL.duk_get_top(ctx));
            DuktapeDLL.duk_put_prop_string(ctx, -3, typename);
            DuktapeDLL.duk_push_object(ctx);                      // [ctor, prototype]
            DuktapeDLL.duk_dup_top(ctx);                          // [ctor, prototype, prototype]
            DuktapeDLL.duk_unity_set_type_refid(ctx, -1, typeid); // prototype.!type == typeid
            DuktapeDLL.duk_push_c_function(ctx, object_dtor, 1);
            DuktapeDLL.duk_set_finalizer(ctx, -3);                // set prototype finalizer
            DuktapeDLL.duk_put_prop_string(ctx, -3, "prototype"); // [ctor, prototype]
        }
Example #11
0
        public static bool duk_get_classvalue(IntPtr ctx, int idx, out DuktapeArray o)
        {
            object obj;

            if (duk_get_cached_object(ctx, idx, out obj))
            {
                if (obj is DuktapeArray)
                {
                    o = (DuktapeArray)obj;
                    return(true);
                }
            }
            if (DuktapeDLL.duk_is_array(ctx, idx))
            {
                DuktapeDLL.duk_dup(ctx, idx);
                var refid = DuktapeDLL.duk_unity_ref(ctx);
                o = new DuktapeArray(ctx, refid);
                return(true);
            }
            o = null;
            return(false);
        }
        protected static void duk_add_event_instanced(IntPtr ctx, string name, DuktapeDLL.duk_c_function add_op, DuktapeDLL.duk_c_function remove_op, int idx)
        {
            idx = DuktapeDLL.duk_normalize_index(ctx, idx);

            int refid;

            DuktapeDLL.duk_unity_get_refid(ctx, idx, out refid); // 直接在 event object 上复制主对象的引用id

            DuktapeDLL.duk_push_object(ctx);                     // [evtobj]
            DuktapeDLL.duk_unity_set_refid(ctx, -1, refid);
            DuktapeDLL.duk_push_string(ctx, name);               // [evtobj, name]
            DuktapeDLL.duk_dup(ctx, -2);                         // [evtobj, name, evtobj]
            DuktapeDLL.duk_push_c_function(ctx, add_op, 1);
            DuktapeDLL.duk_put_prop_string(ctx, -2, "on");
            DuktapeDLL.duk_push_c_function(ctx, remove_op, 1);
            DuktapeDLL.duk_put_prop_string(ctx, -2, "off");
            // [evtobj, name, evtobj]
            DuktapeDLL.duk_def_prop(ctx, idx, DuktapeDLL.DUK_DEFPROP_HAVE_VALUE
                                    | DuktapeDLL.DUK_DEFPROP_SET_ENUMERABLE
                                    | DuktapeDLL.DUK_DEFPROP_CLEAR_CONFIGURABLE);
            // [evtobj]
        }
        public static bool duk_get_classvalue(IntPtr ctx, int idx, out DuktapeFunction o)
        {
            if (DuktapeDLL.duk_is_function(ctx, idx))
            {
                object obj;
                if (duk_get_cached_object(ctx, idx, out obj))
                {
                    if (obj is DuktapeFunction)
                    {
                        o = (DuktapeFunction)obj;
                        return(true);
                    }
                }

                DuktapeDLL.duk_dup(ctx, idx);
                var ptr   = DuktapeDLL.duk_get_heapptr(ctx, -1);
                var refid = DuktapeDLL.duk_unity_ref(ctx);
                o = new DuktapeFunction(ctx, refid, ptr);
                return(true);
            }

            o = null;
            return(false);
        }