예제 #1
0
 public static bool duk_get_primitive(IntPtr ctx, int idx, out sbyte o)
 {
     o = (sbyte)DuktapeDLL.duk_get_int(ctx, idx); // no check
     return(true);
 }
예제 #2
0
        protected static bool duk_match_type(IntPtr ctx, int idx, Type type)
        {
            if (type == null)
            {
                return(true);
            }
            if (type == typeof(object))
            {
                return(true);
            }
            if (type == typeof(Type))
            {
                Type otype;
                return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type
                // return otype == type;
            }
            var jstype = DuktapeDLL.duk_get_type(ctx, idx);

            switch (jstype)
            {
            // case duk_type_t.DUK_TYPE_NONE:
            case duk_type_t.DUK_TYPE_OBJECT:     // objects, arrays, functions, threads
                if (DuktapeDLL.duk_is_array(ctx, idx))
                {
                    if (!type.IsArray && !_assignableFromArray.Contains(type))
                    {
                        return(false);
                    }
                }
                else if (DuktapeDLL.duk_is_function(ctx, idx))
                {
                    //TODO: 完善处理 delegate
                    return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate));
                }
                else if (DuktapeDLL.duk_is_thread(ctx, idx))
                {
                    return(false);
                }
                int refid;
                //TODO: 根据记录在jsobject 上的 分类标记 做进一步分支 (类型, 实例, 或特定优化类型)
                if (duk_get_native_refid(ctx, idx, out refid))
                {
                    var cache = DuktapeVM.GetObjectCache(ctx);
                    return(cache.MatchObjectType(refid, type));
                }
                return(true);

            case duk_type_t.DUK_TYPE_NUMBER:
                return(type.IsPrimitive || type.IsEnum);

            case duk_type_t.DUK_TYPE_STRING:
                return(type == typeof(string));

            case duk_type_t.DUK_TYPE_UNDEFINED:
            case duk_type_t.DUK_TYPE_NULL:
                return(!type.IsValueType && !type.IsPrimitive);

            case duk_type_t.DUK_TYPE_BOOLEAN:
                return(type == typeof(bool));

            case duk_type_t.DUK_TYPE_BUFFER:
                return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */);

            case duk_type_t.DUK_TYPE_POINTER:
            // return type == typeof(DuktapePointer);
            case duk_type_t.DUK_TYPE_LIGHTFUNC:
            default:
                return(false);
            }
        }
예제 #3
0
        protected static bool duk_match_type(IntPtr ctx, int idx, Type type)
        {
            if (type == null)
            {
                return(true);
            }
            if (type == typeof(object))
            {
                return(true);
            }
            if (type == typeof(Type))
            {
                Type otype;
                return(duk_get_type(ctx, idx, out otype)); // 只要求匹配 Type 本身, 不比较具体 Type
                // return otype == type;
            }
            var jstype = DuktapeDLL.duk_get_type(ctx, idx);

            switch (jstype)
            {
            // case duk_type_t.DUK_TYPE_NONE:
            case duk_type_t.DUK_TYPE_OBJECT:     // objects, arrays, functions, threads
                if (DuktapeDLL.duk_is_array(ctx, idx))
                {
                    if (!type.IsArray && !_assignableFromArray.Contains(type))
                    {
                        return(false);
                    }
                }
                else if (DuktapeDLL.duk_is_function(ctx, idx))
                {
                    //TODO: 完善处理 delegate
                    return(type == typeof(DuktapeFunction) || type.BaseType == typeof(MulticastDelegate));
                }
                else if (DuktapeDLL.duk_is_thread(ctx, idx))
                {
                    return(false);
                }

                int refid;
                if (duk_get_native_refid(ctx, idx, out refid))
                {
                    var cache = DuktapeVM.GetObjectCache(ctx);
                    return(cache.MatchObjectType(refid, type));
                }

                int typeid;
                if (DuktapeDLL.duk_unity_get_type_refid(ctx, idx, out typeid))
                {
                    var vm    = DuktapeVM.GetVM(ctx);
                    var eType = vm.GetExportedType(typeid);
                    if (eType != null)
                    {
                        // Debug.LogFormat("match type? {0} {1} {2}", eType, type, typeid);
                        return(eType == type);
                    }
                    // Debug.LogFormat("match type {0} with typeid {1}", type, typeid);
                }
                return(type.IsSubclassOf(typeof(DuktapeValue)));

            case duk_type_t.DUK_TYPE_NUMBER:
                return(type.IsPrimitive || type.IsEnum);

            case duk_type_t.DUK_TYPE_STRING:
                return(type == typeof(string));

            case duk_type_t.DUK_TYPE_UNDEFINED:
            case duk_type_t.DUK_TYPE_NULL:
                return(!type.IsValueType && !type.IsPrimitive);

            case duk_type_t.DUK_TYPE_BOOLEAN:
                return(type == typeof(bool));

            case duk_type_t.DUK_TYPE_BUFFER:
                return(type == typeof(byte[]) || type == typeof(sbyte[]) /* || type == typeof(DuktapeBuffer) */);

            case duk_type_t.DUK_TYPE_POINTER:
            // return type == typeof(DuktapePointer);
            case duk_type_t.DUK_TYPE_LIGHTFUNC:
            default:
                return(false);
            }
        }
예제 #4
0
 protected static void duk_end_class(IntPtr ctx)
 {
     DuktapeDLL.duk_pop_2(ctx); // remove [ctor, prototype]
     // Debug.LogFormat("end class {0}", DuktapeDLL.duk_get_top(ctx));
 }
예제 #5
0
 protected static int object_private_ctor(IntPtr ctx)
 {
     return(DuktapeDLL.duk_generic_error(ctx, "cant call constructor on this type"));
 }
예제 #6
0
 public static void duk_end_namespace(IntPtr ctx)
 {
     DuktapeDLL.duk_pop(ctx);
     // Debug.LogFormat("end namespace {0}", DuktapeDLL.duk_get_top(ctx));
 }
예제 #7
0
 protected static void duk_end_special(IntPtr ctx)
 {
     DuktapeDLL.duk_pop_2(ctx); // remove [ctor, prototype]
 }
예제 #8
0
        private IEnumerator _InitializeStep(IDuktapeListener listener, int step)
        {
            DuktapeDLL.duk_push_global_object(ctx);
            DuktapeJSBuiltins.reg(ctx);
            listener?.OnTypesBinding(this);
            var ctxAsArgs    = new object[] { ctx };
            var bindingTypes = new List <Type>();
            var assemblies   = AppDomain.CurrentDomain.GetAssemblies();

            for (int assemblyIndex = 0, assemblyCount = assemblies.Length; assemblyIndex < assemblyCount; assemblyIndex++)
            {
                var assembly = assemblies[assemblyIndex];
                try
                {
                    if (assembly.IsDynamic)
                    {
                        continue;
                    }
                    var exportedTypes = assembly.GetExportedTypes();
                    for (int i = 0, size = exportedTypes.Length; i < size; i++)
                    {
                        var type = exportedTypes[i];
#if UNITY_EDITOR
                        if (type.IsDefined(typeof(JSAutoRunAttribute), false))
                        {
                            try
                            {
                                var run = type.GetMethod("Run", BindingFlags.Static | BindingFlags.Public);
                                if (run != null)
                                {
                                    run.Invoke(null, null);
                                }
                            }
                            catch (Exception exception)
                            {
                                Debug.LogWarning($"JSAutoRun failed: {exception}");
                            }
                            continue;
                        }
#endif
                        var attributes = type.GetCustomAttributes(typeof(JSBindingAttribute), false);
                        if (attributes.Length == 1)
                        {
                            var jsBinding = attributes[0] as JSBindingAttribute;
                            if (jsBinding.Version == 0 || jsBinding.Version == VERSION)
                            {
                                bindingTypes.Add(type);
                            }
                            else
                            {
                                if (listener != null)
                                {
                                    listener.OnBindingError(this, type);
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Debug.LogErrorFormat("assembly: {0}, {1}", assembly, e);
                }
            }
            var numRegInvoked = bindingTypes.Count;
            for (var i = 0; i < numRegInvoked; ++i)
            {
                var type = bindingTypes[i];
                var reg  = type.GetMethod("reg");
                if (reg != null)
                {
                    reg.Invoke(null, ctxAsArgs);
                    if (listener != null)
                    {
                        listener.OnProgress(this, i, numRegInvoked);
                    }

                    if (i % step == 0)
                    {
                        yield return(null);
                    }
                }
            }
            if (listener != null)
            {
                listener.OnBinded(this, numRegInvoked);
            }
            // Debug.LogFormat("exported {0} classes", _exported.Count);

            // 设置导出类的继承链
            foreach (var kv in _exported)
            {
                var type     = kv.Key;
                var baseType = type.BaseType;
                if (baseType == null)
                {
                    // Debug.Log($"baseType is null, for {type}");
                    continue;
                }
                var fn = kv.Value;
                fn.PushPrototype(ctx);
                if (PushChainedPrototypeOf(ctx, baseType))
                {
                    // Debug.LogFormat($"set {type} super {baseType}");
                    DuktapeDLL.duk_set_prototype(ctx, -2);
                }
                else
                {
                    Debug.LogWarning($"fail to push prototype, for {type}: {baseType}");
                }
                DuktapeDLL.duk_pop(ctx);
            }

            DuktapeJSBuiltins.postreg(ctx);
            DuktapeDLL.duk_pop(ctx); // pop global

            _updateTimer = DuktapeRunner.SetInterval(this.OnUpdate, 100);

            if (listener != null)
            {
                listener.OnLoaded(this);
            }
        }
 public static void duk_push_structvalue(IntPtr ctx, Quaternion o)
 {
     DuktapeDLL.duk_unity_push_quaternion(ctx, o.x, o.y, o.z, o.w);
 }
예제 #10
0
 public void PushProperty(IntPtr ctx, string property)
 {
     this.Push(ctx);                 // push this
     DuktapeDLL.duk_get_prop_string(ctx, -1, property);
     DuktapeDLL.duk_remove(ctx, -2); // remove this
 }
예제 #11
0
 public void GetMemoryState(out uint count, out uint size, out uint poolSize)
 {
     poolSize = _memAllocPoolSize;
     DuktapeDLL.duk_unity_get_memory_state(ctx, out count, out size);
 }
예제 #12
0
 private static void duk_unity_unref(IntPtr ctx, uint refid, object target)
 {
     DuktapeDLL.duk_unity_unref(ctx, refid);
 }
예제 #13
0
 public void PushProperty(IntPtr ctx, uint index)
 {
     this.Push(ctx);                 // push this
     DuktapeDLL.duk_get_prop_index(ctx, -1, index);
     DuktapeDLL.duk_remove(ctx, -2); // remove this
 }
예제 #14
0
        public static bool duk_get_var(IntPtr ctx, int idx, out object o)
        {
            var jstype = DuktapeDLL.duk_get_type(ctx, idx);

            switch (jstype)
            {
            case duk_type_t.DUK_TYPE_BOOLEAN:     /* ECMAScript boolean: 0 or 1 */
                {
                    o = DuktapeDLL.duk_get_boolean(ctx, idx);
                    return(true);
                }

            case duk_type_t.DUK_TYPE_NUMBER:     /* ECMAScript number: double */
            {
                o = DuktapeDLL.duk_get_number(ctx, idx);
                return(true);
            }

            case duk_type_t.DUK_TYPE_STRING:     /* ECMAScript string: CESU-8 / extended UTF-8 encoded */
            {
                o = DuktapeDLL.duk_get_string(ctx, idx);
                return(true);
            }

            case duk_type_t.DUK_TYPE_OBJECT:     /* ECMAScript object: includes objects, arrays, functions, threads */
            {
                if (DuktapeDLL.duk_is_function(ctx, idx))
                {
                    DuktapeFunction func;
                    var             r = duk_get_classvalue(ctx, idx, out func);
                    o = func;
                    return(r);
                }
                if (duk_get_cached_object(ctx, idx, out o))
                {
                    return(true);
                }
                else
                {
                    DuktapeObject val;
                    var           r = duk_get_classvalue(ctx, idx, out val);
                    o = val;
                    return(r);
                }
            }

            case duk_type_t.DUK_TYPE_BUFFER:     /* fixed or dynamic, garbage collected byte buffer */
            {
                uint length;
                var  pointer = DuktapeDLL.duk_unity_get_buffer_data(ctx, idx, out length);
                var  buffer  = new byte[length];
                o = buffer;
                Marshal.Copy(pointer, buffer, 0, (int)length);
                return(true);
            }

            case duk_type_t.DUK_TYPE_POINTER:        /* raw void pointer */
            case duk_type_t.DUK_TYPE_LIGHTFUNC:      /* lightweight function pointer */
                throw new NotImplementedException();

            case duk_type_t.DUK_TYPE_NONE:        /* no value, e.g. invalid index */
                o = null;
                return(false);

            case duk_type_t.DUK_TYPE_UNDEFINED:   /* ECMAScript undefined */
            case duk_type_t.DUK_TYPE_NULL:        /* ECMAScript null */
                o = null;
                return(true);
            }

            o = null;
            return(false);
        }
예제 #15
0
 private static void duk_unity_unref(IntPtr ctx, uint refid, object target)
 {
     DuktapeVM.GetObjectCache(ctx).RemoveJSValue(target);
     DuktapeDLL.duk_unity_unref(ctx, refid);
 }
 public static void duk_push_primitive(IntPtr ctx, bool o)
 {
     DuktapeDLL.duk_push_boolean(ctx, o);
 }
예제 #17
0
 public static void duk_begin_namespace(IntPtr ctx, string el1, string el2) // [parent]
 {
     duk_begin_namespace(ctx, el1);                                         // [parent, el1]
     duk_begin_namespace(ctx, el2);                                         // [parent, el1, el2]
     DuktapeDLL.duk_remove(ctx, -2);                                        // [parent, el2]
 }
 public static void duk_push_primitive(IntPtr ctx, string o)
 {
     DuktapeDLL.duk_push_string(ctx, o);
 }
예제 #19
0
 protected static void duk_end_object(IntPtr ctx)
 {
     DuktapeDLL.duk_pop(ctx);
 }
 public static void duk_push_primitive(IntPtr ctx, uint o)
 {
     DuktapeDLL.duk_push_uint(ctx, o);
 }
예제 #21
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_unity_set_type_refid(ctx, -2, 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]
        }
 public static void duk_push_primitive(IntPtr ctx, double o)
 {
     DuktapeDLL.duk_push_number(ctx, o);
 }
예제 #23
0
 protected static void duk_add_method(IntPtr ctx, string name, DuktapeDLL.duk_c_function func, int idx)
 {
     idx = DuktapeDLL.duk_normalize_index(ctx, idx);
     DuktapeDLL.duk_push_c_function(ctx, func, DuktapeDLL.DUK_VARARGS);
     DuktapeDLL.duk_put_prop_string(ctx, idx, name);
 }
 public static void duk_push_structvalue(IntPtr ctx, LayerMask o)
 {
     DuktapeDLL.duk_push_int(ctx, (int)o);
 }
예제 #25
0
 // 无命名空间, 直接外围对象作为容器 (通常是global)
 public static void duk_begin_namespace(IntPtr ctx) // [parent]
 {
     // Debug.LogFormat("begin namespace {0}", DuktapeDLL.duk_get_top(ctx));
     DuktapeDLL.duk_dup_top(ctx); // [parent, parent]
 }
 public static void duk_push_structvalue(IntPtr ctx, Color32 o)
 {
     DuktapeDLL.duk_unity_push_color32(ctx, o.r, o.g, o.b, o.a);
 }
예제 #27
0
 public static int duk_enableStacktrace(IntPtr ctx)
 {
     printStacktrace = DuktapeDLL.duk_require_boolean(ctx, 0);
     return(0);
 }
 public static void duk_push_structvalue(IntPtr ctx, Vector2 o)
 {
     DuktapeDLL.duk_unity_push_vector2(ctx, o.x, o.y);
 }
예제 #29
0
 public static bool duk_get_primitive(IntPtr ctx, int idx, out uint o)
 {
     o = DuktapeDLL.duk_get_uint(ctx, idx); // no check
     return(true);
 }
예제 #30
0
 public static bool duk_get_structvalue(IntPtr ctx, int idx, out LayerMask o)
 {
     o = (LayerMask)DuktapeDLL.duk_get_int(ctx, idx);
     return(true);
 }