public static bool duk_get_type(IntPtr ctx, int idx, out Type o)
 {
     if (DuktapeDLL.duk_is_string(ctx, idx))
     {
         var name = DuktapeDLL.duk_get_string(ctx, idx);
         o = DuktapeAux.GetType(name);
         return(o != null);
     }
     else
     {
         //TODO: 增加一个隐藏属性记录jsobject对应类型 (constructor, object)
         if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_EXPORTED_REFID))
         {
             var vm    = DuktapeVM.GetVM(ctx);
             var refid = DuktapeDLL.duk_get_uint(ctx, -1);
             DuktapeDLL.duk_pop(ctx);
             o = vm.GetExportedType(refid);
             // Debug.Log($"get type from exported registry {o}:{refid}");
             return(o != null);
         }
         else if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
         {
             var cache = DuktapeVM.GetObjectCache(ctx);
             var refid = DuktapeDLL.duk_get_int(ctx, -1);
             DuktapeDLL.duk_pop(ctx);
             cache.TryGetTypedObject(refid, out o);
             // Debug.Log($"get type from objectcache registry {o}:{refid}");
             return(o != null);
         }
     }
     o = null;
     return(false);
 }
Exemplo n.º 2
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>
        }
Exemplo n.º 3
0
        private static duk_ret_t cb_load_module(IntPtr ctx)
        {
            var module_id = DuktapeAux.duk_require_string(ctx, 0);

            DuktapeDLL.duk_get_prop_string(ctx, 2, "filename");
            var filename = DuktapeAux.duk_require_string(ctx, -1);
            var source   = GetVM(ctx)._fileResolver.ReadAllBytes(filename);

            // Debug.LogFormat("cb_load_module module_id:'{0}', filename:'{1}', resolved:'{2}'\n", module_id, filename, resolvedPath);
            do
            {
                if (source != null && source.Length > 0) // bytecode is unsupported
                {
                    if (source[0] != 0xbf)
                    {
                        DuktapeDLL.duk_unity_push_lstring(ctx, source, (uint)source.Length);
                    }
                    else
                    {
                        DuktapeDLL.duk_type_error(ctx, "cannot load module (bytecode): %s", module_id);
                    }
                    break;
                }
                DuktapeDLL.duk_type_error(ctx, "cannot load module: %s", module_id);
            } while (false);
            return(1);
        }
Exemplo n.º 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);
        }
Exemplo n.º 5
0
        private static string duk_get_stacktrace(IntPtr ctx)
        {
            var stacktrace = "stacktrace:\n";

            for (int i = -2; ; i--)
            {
                DuktapeDLL.duk_inspect_callstack_entry(ctx, i);
                if (!DuktapeDLL.duk_is_undefined(ctx, -1))
                {
                    DuktapeDLL.duk_get_prop_string(ctx, -1, "lineNumber");
                    var lineNumber = DuktapeDLL.duk_to_int(ctx, -1);
                    DuktapeDLL.duk_get_prop_string(ctx, -2, "function");
                    DuktapeDLL.duk_get_prop_string(ctx, -1, "name");
                    var funcName = DuktapeDLL.duk_safe_to_string(ctx, -1);
                    DuktapeDLL.duk_get_prop_string(ctx, -2, "fileName");
                    var fileName = DuktapeDLL.duk_safe_to_string(ctx, -1);
                    DuktapeDLL.duk_pop_n(ctx, 4);
                    stacktrace += (duk_source_position ?? default_duk_source_position)(ctx, funcName, fileName, lineNumber);
                    stacktrace += "\n";
                }
                else
                {
                    DuktapeDLL.duk_pop(ctx);
                    break;
                }
            }
            return(stacktrace);
        }
Exemplo n.º 6
0
 protected static int object_dtor(IntPtr ctx)
 {
     if (DuktapeDLL.duk_get_prop_string(ctx, 0, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeVM.GetObjectCache(ctx)?.RemoveObject(id);
     }
     DuktapeDLL.duk_pop(ctx); // pop native
     return(0);
 }
Exemplo n.º 7
0
 public static bool duk_retrive_object(IntPtr ctx, string el0)
 {
     DuktapeDLL.duk_dup_top(ctx);
     if (!DuktapeDLL.duk_get_prop_string(ctx, -1, el0)) // [parent, el0]
     {
         DuktapeDLL.duk_remove(ctx, -2);
         return(false);
     }
     DuktapeDLL.duk_remove(ctx, -2);
     return(true);
 }
Exemplo n.º 8
0
        public static void PrintError(IntPtr ctx, int idx, string filename)
        {
            string err;

            if (DuktapeDLL.duk_is_error(ctx, idx))
            {
                DuktapeDLL.duk_get_prop_string(ctx, idx, "stack");
                err = DuktapeDLL.duk_safe_to_string(ctx, -1);
                DuktapeDLL.duk_pop(ctx);
            }
            else
            {
                err = DuktapeDLL.duk_safe_to_string(ctx, idx);
            }

            if (duk_source_position != default_duk_source_position)
            {
                var errlines = err.Split('\n');
                err = "";
                if (_stRegex == null)
                {
                    _stRegex = new Regex(@"^\s+at\s(.+)\s\((.+\.js):(\d+)\)(.*)$", RegexOptions.Compiled);
                }
                for (var i = 0; i < errlines.Length; i++)
                {
                    var line    = errlines[i];
                    var matches = _stRegex.Matches(line);
                    if (matches.Count == 1)
                    {
                        var match = matches[0];
                        if (match.Groups.Count >= 4)
                        {
                            var funcName   = match.Groups[1].Value;
                            var fileName   = match.Groups[2].Value;
                            var lineNumber = 0;
                            int.TryParse(match.Groups[3].Value, out lineNumber);
                            var extra          = match.Groups.Count >= 5 ? match.Groups[4].Value : "";
                            var sroucePosition = duk_source_position(ctx, funcName, fileName, lineNumber);
                            err += $"    at {sroucePosition}{extra}\n";
                            continue;
                        }
                    }
                    err += line + "\n";
                }
            }
            if (filename != null)
            {
                Debug.LogError($"[JSError][{filename}] {err}");
            }
            else
            {
                Debug.LogError($"[JSError] {err}");
            }
        }
Exemplo n.º 9
0
 public static void duk_begin_namespace(IntPtr ctx, string el) // [parent]
 {
     // Debug.LogFormat("begin namespace {0}", DuktapeDLL.duk_get_top(ctx));
     if (!DuktapeDLL.duk_get_prop_string(ctx, -1, el)) // [parent, el]
     {
         DuktapeDLL.duk_pop(ctx);                      // [parent]
         DuktapeDLL.duk_push_object(ctx);              // [parent, new_object]
         DuktapeDLL.duk_dup_top(ctx);                  // [parent, new_object]
         DuktapeDLL.duk_put_prop_string(ctx, -3, el);  // [parent, el]
     }
 }
Exemplo n.º 10
0
 // 获取全局函数并调用 (do not cache it)
 public void Invoke(string funcName)
 {
     DuktapeDLL.duk_push_global_object(_ctx);
     DuktapeDLL.duk_get_prop_string(_ctx, -1, funcName);
     if (DuktapeDLL.duk_is_function(_ctx, -1))
     {
         if (DuktapeDLL.duk_pcall(_ctx, 0) != DuktapeDLL.DUK_EXEC_SUCCESS)
         {
             DuktapeAux.PrintError(_ctx, -1);
         }
     }
     DuktapeDLL.duk_pop_2(_ctx);
 }
Exemplo n.º 11
0
        // public static bool duk_rebind_this(IntPtr ctx, Matrix4x4 o)
        // {
        //     DuktapeDLL.duk_push_this(ctx);
        //     DuktapeDLL.duk_unity_put16f(ctx, -1, ...);
        //     DuktapeDLL.duk_pop(ctx);
        //     return true;
        // }

        public static bool duk_get_native_refid(IntPtr ctx, int idx, out int id)
        {
            if (!DuktapeDLL.duk_is_null_or_undefined(ctx, idx))
            {
                if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
                {
                    id = DuktapeDLL.duk_get_int(ctx, -1);
                    return(true);
                }
                DuktapeDLL.duk_pop(ctx); // pop OBJ_PROP_NATIVE
            }
            id = 0;
            return(false);
        }
Exemplo n.º 12
0
 public static bool duk_retrive_object(IntPtr ctx, params string[] els)
 {
     DuktapeDLL.duk_dup_top(ctx);
     for (int i = 1, size = els.Length; i < size; i++)
     {
         var el = els[i];
         if (!DuktapeDLL.duk_get_prop_string(ctx, -1, el)) // [parent, el]
         {
             DuktapeDLL.duk_remove(ctx, -2);
             return(false);
         }
         DuktapeDLL.duk_remove(ctx, -2);
     }
     return(true);
 }
Exemplo n.º 13
0
 public static bool duk_get_cached_object(IntPtr ctx, int idx, out object o)
 {
     if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeDLL.duk_pop(ctx);
         return(DuktapeVM.GetObjectCache(ctx).TryGetObject(id, out o));
     }
     else
     {
         DuktapeDLL.duk_pop(ctx);
     }
     o = null;
     return(false);
 }
Exemplo n.º 14
0
        protected static void duk_add_event(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);

            DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE); // 直接在 event object 上复制主对象的引用id
            var refid = DuktapeDLL.duk_get_int(ctx, -1);

            DuktapeDLL.duk_pop(ctx);

            DuktapeDLL.duk_push_object(ctx);
            DuktapeDLL.duk_unity_set_prop_i(ctx, -1, DuktapeVM.OBJ_PROP_NATIVE, refid);
            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");
            DuktapeDLL.duk_put_prop_string(ctx, idx, name);
        }
Exemplo n.º 15
0
 // 记录栈状态
 public void BeginInvoke(IntPtr ctx)
 {
     // Debug.Log($"BeginInvoke: {_savedState}");
     if (_jsInvoker == null)
     {
         this.Push(ctx); // push this
         if (!DuktapeDLL.duk_is_function(ctx, -1))
         {
             // Debug.Log("DuktapeDelegate based on Dispatcher");
             DuktapeDLL.duk_get_prop_string(ctx, -1, "dispatch");
             DuktapeDLL.duk_remove(ctx, -2); // remove this
         }
         _jsInvoker = new DuktapeFunction(ctx, DuktapeDLL.duk_unity_ref(ctx));
     }
     _jsInvoker.Push(ctx); // push function
     this.Push(ctx);       // push this
     _savedState = DuktapeDLL.duk_get_top(ctx);
 }
Exemplo n.º 16
0
 public static bool duk_rebind_native(IntPtr ctx, int idx, object o)
 {
     if (DuktapeDLL.duk_is_null_or_undefined(ctx, idx)) // or check for object?
     {
         return(true);
     }
     if (DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE))
     {
         var id = DuktapeDLL.duk_get_int(ctx, -1);
         DuktapeDLL.duk_pop(ctx); // pop OBJ_PROP_NATIVE
         return(DuktapeVM.GetObjectCache(ctx).ReplaceObject(id, o));
     }
     else
     {
         DuktapeDLL.duk_pop(ctx);
     }
     return(false);
 }
Exemplo n.º 17
0
        private static string duk_get_stacktrace(IntPtr ctx)
        {
            var  stacktrace   = "\n";
            uint malloc_count = 0;
            uint malloc_size  = 0;
            var  vm           = DuktapeVM.GetVM(ctx);

            if (vm != null)
            {
                vm.GetMemoryState(out malloc_count, out malloc_size);
                if (malloc_count != 0)
                {
                    stacktrace += $"allocations: {malloc_count} [{malloc_size}]\n";
                }
            }
            stacktrace += "stacktrace:\n";
            for (int i = -2; ; i--)
            {
                DuktapeDLL.duk_inspect_callstack_entry(ctx, i);
                if (!DuktapeDLL.duk_is_undefined(ctx, -1))
                {
                    DuktapeDLL.duk_get_prop_string(ctx, -1, "lineNumber");
                    var lineNumber = DuktapeDLL.duk_to_int(ctx, -1);
                    DuktapeDLL.duk_get_prop_string(ctx, -2, "function");
                    DuktapeDLL.duk_get_prop_string(ctx, -1, "name");
                    var funcName = DuktapeDLL.duk_safe_to_string(ctx, -1);
                    DuktapeDLL.duk_get_prop_string(ctx, -2, "fileName");
                    var fileName = DuktapeDLL.duk_safe_to_string(ctx, -1);
                    DuktapeDLL.duk_pop_n(ctx, 4);
                    stacktrace += (duk_source_position ?? default_duk_source_position)(ctx, funcName, fileName, lineNumber);
                    stacktrace += "\n";
                }
                else
                {
                    DuktapeDLL.duk_pop(ctx);
                    break;
                }
            }
            return(stacktrace);
        }
Exemplo n.º 18
0
        private static duk_ret_t cb_load_module(IntPtr ctx)
        {
            var module_id = DuktapeAux.duk_require_string(ctx, 0);

            DuktapeDLL.duk_get_prop_string(ctx, 2, "filename");
            var filename     = DuktapeAux.duk_require_string(ctx, -1);
            var resolvedPath = GetVM(ctx).ResolvePath(filename);
            // Debug.LogFormat("cb_load_module module_id:'{0}', filename:'{1}', resolved:'{2}'\n", module_id, filename, resolvedPath);

            var source = GetVM(ctx)._fileManager.ReadAllText(resolvedPath);

            if (source != null)
            {
                DuktapeDLL.duk_push_string(ctx, source);
            }
            else
            {
                DuktapeDLL.duk_type_error(ctx, "cannot load module: %s", module_id);
            }

            return(1);
        }
Exemplo n.º 19
0
        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);

            DuktapeDLL.duk_get_prop_string(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE); // 直接在 event object 上复制主对象的引用id
            var refid = DuktapeDLL.duk_get_int(ctx, -1);

            DuktapeDLL.duk_pop(ctx);

            DuktapeDLL.duk_push_object(ctx);       // [evtobj]
            DuktapeDLL.duk_unity_set_prop_i(ctx, -1, DuktapeVM.OBJ_PROP_NATIVE, 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]
        }
Exemplo n.º 20
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
 }
Exemplo n.º 21
0
 // push 当前函数的 prototype
 public void PushPrototype(IntPtr ctx)
 {
     this.Push(ctx);
     DuktapeDLL.duk_get_prop_string(ctx, -1, "prototype");
     DuktapeDLL.duk_remove(ctx, -2);
 }