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); }
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); }
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); }
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); }
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> }
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); }
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 }
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); }
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] }
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] }
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); }