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 { uint refid_t; //TODO: 增加一个隐藏属性记录jsobject对应类型 (constructor, object) if (DuktapeDLL.duk_unity_get_type_refid(ctx, idx, out refid_t)) { var vm = DuktapeVM.GetVM(ctx); o = vm.GetExportedType(refid_t); // Debug.Log($"get type from exported registry {o}:{refid}"); return(o != null); } else { int refid; if (DuktapeDLL.duk_unity_get_refid(ctx, idx, out refid)) { var cache = DuktapeVM.GetObjectCache(ctx); cache.TryGetTypedObject(refid, out o); // Debug.Log($"get type from objectcache registry {o}:{refid}"); return(o != null); } } } o = null; return(false); }
public static void duk_bind_native(IntPtr ctx, int idx, object o) { var type = o.GetType(); var vm = DuktapeVM.GetVM(ctx); var cache = vm.GetObjectCache(); var id = cache.AddObject(o); if (id >= 0) { DuktapeDLL.duk_unity_set_refid(ctx, idx, id); } if (DuktapeVM.GetVM(ctx).PushChainedPrototypeOf(ctx, type)) { DuktapeDLL.duk_set_prototype(ctx, -2); } else { Debug.LogWarning($"no prototype found for {type}"); } if (!type.IsValueType) { var heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx); cache.AddJSValue(o, heapptr); } }
public static bool duk_get_classvalue(IntPtr ctx, int idx, out IO.ByteBuffer o) { object obj; if (duk_get_cached_object(ctx, idx, out obj)) { if (obj is IO.ByteBuffer) { o = (IO.ByteBuffer)obj; return(true); } } if (DuktapeDLL.duk_is_buffer_data(ctx, idx)) { var allocator = DuktapeVM.GetVM(ctx).GetByteBufferAllocator(); if (allocator != null) { uint length; var pointer = DuktapeDLL.duk_unity_get_buffer_data(ctx, idx, out length); o = allocator.Alloc((int)length); allocator.AutoRelease(o); o.WriteBytes(pointer, (int)length); return(true); } } 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)) { 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 SourceMap GetSourceMap(IntPtr ctx, string fileName) { SourceMap sourceMap; if (!_sourceMaps.TryGetValue(fileName, out sourceMap)) { try { var vm = DuktapeVM.GetVM(ctx); var resolvedPath = vm.ResolvePath(fileName + ".map"); if (resolvedPath != null) { using (var stream = File.OpenRead(resolvedPath)) { var parser = new SourceMapParser(); var reader = new StreamReader(stream); sourceMap = parser.ParseSourceMap(reader); // Debug.Log($"[SourceMapHelper] parse sourceMap: {sourceMap.File} ({resolvedPath})"); } } } finally { _sourceMaps[fileName] = sourceMap; } } return(sourceMap); }
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 SourceMap GetSourceMap(IntPtr ctx, string fileName) { SourceMap sourceMap; if (!_sourceMaps.TryGetValue(fileName, out sourceMap)) { try { var fileResolver = DuktapeVM.GetVM(ctx).fileResolver; var fileContent = fileResolver.ReadAllBytes(fileName + ".map"); if (fileContent != null && fileContent.Length > 0) { using (var stream = new MemoryStream(fileContent)) { var parser = new SourceMapParser(); var reader = new StreamReader(stream); sourceMap = parser.ParseSourceMap(reader); // Debug.Log($"[SourceMapHelper] parse sourceMap: {sourceMap.File} ({resolvedPath})"); } } } finally { _sourceMaps[fileName] = sourceMap; } } return(sourceMap); }
public static int duk_dofile(IntPtr ctx) { var filename = DuktapeAux.duk_require_string(ctx, 0); DuktapeVM.GetVM(ctx).EvalFile(filename); return(0); }
public static int duk_addSearchPath(IntPtr ctx) { var path = DuktapeAux.duk_require_string(ctx, 0); DuktapeVM.GetVM(ctx).AddSearchPath(path); return(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); }
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); }
public static int duk_dostring(IntPtr ctx) { var source = DuktapeDLL.duk_get_string(ctx, 0); var filename = DuktapeDLL.duk_get_string(ctx, 1); DuktapeVM.GetVM(ctx).EvalSource(source, filename); return(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 }
public static int duk_dostring(IntPtr ctx) { // var source = DuktapeDLL.duk_get_string(ctx, 0); uint len; var buffer_ptr = DuktapeDLL.duk_unity_get_lstring(ctx, 0, out len); if (len > 0) { var bytes = new byte[len]; Marshal.Copy(buffer_ptr, bytes, 0, (int)len); var filename = DuktapeDLL.duk_get_string(ctx, 1); DuktapeVM.GetVM(ctx).EvalSource(filename, bytes); } return(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] }
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 void duk_bind_native(IntPtr ctx, int idx, object o) { var cache = DuktapeVM.GetObjectCache(ctx); var id = cache.AddObject(o); DuktapeDLL.duk_unity_set_prop_i(ctx, idx, DuktapeVM.OBJ_PROP_NATIVE, id); if (DuktapeVM.GetVM(ctx).PushChainedPrototypeOf(ctx, o.GetType())) { DuktapeDLL.duk_set_prototype(ctx, -2); } else { Debug.LogWarning($"no prototype found for {o.GetType()}"); } if (!o.GetType().IsValueType) { var heapptr = DuktapeDLL.duk_get_heapptr(ctx, idx); cache.AddJSValue(o, heapptr); } }
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); }
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); } }