(ctor, obj, m)
| 9915 | /** Frees the obj.pointer memory (a.k.a. m), handles obj.ondispose, |
| 9916 | and unmaps obj from its native resources. */ |
| 9917 | const __freeStruct = function(ctor, obj, m){ |
| 9918 | const ii = getInstanceHandle(obj, false); |
| 9919 | if( !ii ) return; |
| 9920 | rmInstanceHandle(obj); |
| 9921 | if( !m && !(m = ii.p) ){ |
| 9922 | console.warn("Cannot(?) happen: __freeStruct() found no instanceInfo"); |
| 9923 | return; |
| 9924 | } |
| 9925 | if(Array.isArray(obj.ondispose)){ |
| 9926 | let x; |
| 9927 | while((x = obj.ondispose.pop())){ |
| 9928 | try{ |
| 9929 | if(x instanceof Function) x.call(obj); |
| 9930 | else if(x instanceof StructType) x.dispose(); |
| 9931 | else if(__isPtr(x)) dealloc(x); |
| 9932 | // else ignore. Strings are permitted to annotate entries |
| 9933 | // to assist in debugging. |
| 9934 | }catch(e){ |
| 9935 | console.warn("ondispose() for",ctor.structName,'@', |
| 9936 | m,'threw. NOT propagating it.',e); |
| 9937 | } |
| 9938 | } |
| 9939 | }else if(obj.ondispose instanceof Function){ |
| 9940 | try{obj.ondispose()} |
| 9941 | catch(e){ |
| 9942 | /*do not rethrow: destructors must not throw*/ |
| 9943 | console.warn("ondispose() for",ctor.structName,'@', |
| 9944 | m,'threw. NOT propagating it.',e); |
| 9945 | } |
| 9946 | } |
| 9947 | delete obj.ondispose; |
| 9948 | if(ctor.debugFlags.__flags.dealloc){ |
| 9949 | log("debug.dealloc:",(ii.ownsPointer?"":"EXTERNAL"), |
| 9950 | ctor.structName,"instance:", |
| 9951 | ctor.structInfo.sizeof,"bytes @"+m); |
| 9952 | } |
| 9953 | if(ii.ownsPointer){ |
| 9954 | if( ii.zod || ctor.structInfo.zeroOnDispose ){ |
| 9955 | heap().fill(0, Number(m), |
| 9956 | Number(m) + ctor.structInfo.sizeof + ii.xb); |
| 9957 | } |
| 9958 | dealloc(m); |
| 9959 | } |
| 9960 | }; |
| 9961 | |
| 9962 | /** Returns a skeleton for a read-only, non-iterable property |
| 9963 | * descriptor. */ |
no test coverage detected