quickjs-emscripten-sync 1.9.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,23 +1,23 @@
1
- (function(m,w){typeof exports=="object"&&typeof module!="undefined"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(m=typeof globalThis!="undefined"?globalThis:m||self,w(m.QuickjsEmscriptenSync={}))})(this,(function(m){"use strict";var Fe=Object.defineProperty;var x=Object.getOwnPropertySymbols;var Ie=Object.prototype.hasOwnProperty,Ne=Object.prototype.propertyIsEnumerable;var G=(m,w,g)=>w in m?Fe(m,w,{enumerable:!0,configurable:!0,writable:!0,value:g}):m[w]=g,ee=(m,w)=>{for(var g in w||(w={}))Ie.call(w,g)&&G(m,g,w[g]);if(x)for(var g of x(w))Ne.call(w,g)&&G(m,g,w[g]);return m};var p=(m,w,g)=>G(m,typeof w!="symbol"?w+"":w,g);var te=(m,w,g)=>new Promise((M,k)=>{var I=O=>{try{H(g.next(O))}catch(y){k(y)}},T=O=>{try{H(g.throw(O))}catch(y){k(y)}},H=O=>O.done?M(O.value):Promise.resolve(O.value).then(I,T);H((g=g.apply(m,w)).next())});const w=n=>{const e=new g(n);return new Proxy(n,{get(t,r,s){return r in e?e[r]:Reflect.get(t,r,s)}})};class g{constructor(e){p(this,"context");p(this,"fn");p(this,"fnGenerator");p(this,"fnCounter",Number.MIN_SAFE_INTEGER);p(this,"fnMap",new Map);p(this,"newFunction",(e,t)=>{this.fnCounter++;const r=this.fnCounter;return this.fnMap.set(r,t),this.context.unwrapResult(this.context.callFunction(this.fnGenerator,this.context.undefined,this.context.newString(e),this.context.newNumber(t.length),this.context.newNumber(r),this.fn))});this.context=e;const t=this.fnMap;this.fn=this.context.newFunction("",function(r,...s){const i=e.getNumber(r),o=t.get(i);if(!o)throw new Error("function is not registered");return o.call(this,...s)}),this.fnGenerator=e.unwrapResult(e.evalCode(`((name, length, id, f) => {
1
+ (function(_,b){typeof exports=="object"&&typeof module!="undefined"?b(exports):typeof define=="function"&&define.amd?define(["exports"],b):(_=typeof globalThis!="undefined"?globalThis:_||self,b(_.QuickjsEmscriptenSync={}))})(this,(function(_){"use strict";var Fe=Object.defineProperty;var ee=Object.getOwnPropertySymbols;var Ie=Object.prototype.hasOwnProperty,Ne=Object.prototype.propertyIsEnumerable;var J=(_,b,g)=>b in _?Fe(_,b,{enumerable:!0,configurable:!0,writable:!0,value:g}):_[b]=g,te=(_,b)=>{for(var g in b||(b={}))Ie.call(b,g)&&J(_,g,b[g]);if(ee)for(var g of ee(b))Ne.call(b,g)&&J(_,g,b[g]);return _};var p=(_,b,g)=>J(_,typeof b!="symbol"?b+"":b,g);var ne=(_,b,g)=>new Promise((A,k)=>{var I=O=>{try{C(g.next(O))}catch(h){k(h)}},R=O=>{try{C(g.throw(O))}catch(h){k(h)}},C=O=>O.done?A(O.value):Promise.resolve(O.value).then(I,R);C((g=g.apply(_,b)).next())});const b=n=>{const e=new g(n);return new Proxy(n,{get(t,r,s){return r in e?e[r]:Reflect.get(t,r,s)}})};class g{constructor(e){p(this,"context");p(this,"fn");p(this,"fnGenerator");p(this,"fnCounter",Number.MIN_SAFE_INTEGER);p(this,"fnMap",new Map);p(this,"newFunction",(e,t)=>{this.fnCounter++;const r=this.fnCounter;return this.fnMap.set(r,t),this.context.unwrapResult(this.context.callFunction(this.fnGenerator,this.context.undefined,this.context.newString(e),this.context.newNumber(t.length),this.context.newNumber(r),this.fn))});this.context=e;const t=this.fnMap;this.fn=this.context.newFunction("",function(r,...s){const i=e.getNumber(r),o=t.get(i);if(!o)throw new Error("function is not registered");return o.call(this,...s)}),this.fnGenerator=e.unwrapResult(e.evalCode(`((name, length, id, f) => {
2
2
  const fn = function(...args) {
3
3
  return f.call(this, id, ...args);
4
4
  };
5
5
  fn.name = name;
6
6
  fn.length = length;
7
7
  return fn;
8
- })`))}disposeEx(){this.fnGenerator.dispose(),this.fn.dispose()}}const M=[[Symbol,"Symbol"],[Symbol.prototype,"Symbol.prototype"],[Object,"Object"],[Object.prototype,"Object.prototype"],[Function,"Function"],[Function.prototype,"Function.prototype"],[Boolean,"Boolean"],[Boolean.prototype,"Boolean.prototype"],[Array,"Array"],[Array.prototype,"Array.prototype"],[Error,"Error"],[Error.prototype,"Error.prototype"],[EvalError,"EvalError"],[EvalError.prototype,"EvalError.prototype"],[RangeError,"RangeError"],[RangeError.prototype,"RangeError.prototype"],[ReferenceError,"ReferenceError"],[ReferenceError.prototype,"ReferenceError.prototype"],[SyntaxError,"SyntaxError"],[SyntaxError.prototype,"SyntaxError.prototype"],[TypeError,"TypeError"],[TypeError.prototype,"TypeError.prototype"],[URIError,"URIError"],[URIError.prototype,"URIError.prototype"],...Object.getOwnPropertyNames(Symbol).filter(n=>typeof Symbol[n]=="symbol").map(n=>[Symbol[n],`Symbol.${n}`])];function k(n,e){if("error"in e&&e.error){const{error:t}=e;let r;try{r=n.dump(t)}catch(i){}finally{t.alive&&t.dispose()}const s=new Error(typeof r=="object"&&r&&"message"in r?String(r.message):r!==void 0?String(r):"quickjs-emscripten-sync: VM evaluation failed");throw typeof r=="object"&&r&&("name"in r&&(s.name=String(r.name)),"stack"in r&&(s.stack=String(r.stack))),s}return e.value}function I(n,e){const t=k(n,n.evalCode(e)),r=(i,...o)=>k(n,n.callFunction(t,i!=null?i:n.undefined,...o)),s=()=>t.dispose();return r.dispose=s,r[Symbol.dispose]=s,Object.defineProperty(r,"alive",{get:()=>t.alive}),r}const T=new WeakMap;function H(n){T.has(n)||T.set(n,new Map)}function O(n){const e=T.get(n);if(e){for(const t of e.values())t.alive&&t.dispose();T.delete(n)}}function y(n,e,t,...r){const s=T.get(n);if(!s){const o=I(n,e);try{return o(t,...r)}finally{o.dispose()}}let i=s.get(e);return(!i||!i.alive)&&(i=k(n,n.evalCode(e)),s.set(e,i)),k(n,n.callFunction(i,t!=null?t:n.undefined,...r))}function ne(n,e,t){return n.dump(y(n,"(a, b) => a instanceof b",void 0,e,t))}function J(n,e){const t=n.typeof(e);return t==="function"||t==="object"&&!n.sameValue(e,n.null)}function W(n,e){const t=JSON.stringify(e);return t?y(n,"JSON.parse",void 0,n.newString(t)):n.undefined}function S(n,e){try{return e(n)}finally{n.alive&&n.dispose()}}function z(n,e){try{return e(n)}finally{for(const t of n)t.alive&&t.dispose()}}function re([n,e],t){try{return t(n)}finally{e&&n.dispose()}}function C(n,e){try{return e(...n.map(t=>t[0]))}finally{for(const[t,r]of n)r&&t.dispose()}}function se(n){return"handle"in n}function ie(n){return se(n)?n.handle:n}function oe(n,e,t,r){var i;let s;for(const o of r)if(s=o(e,n),s)break;return s?(i=t(e,s))!=null?i:s:void 0}function ue(n,e){return typeof n!="symbol"?void 0:y(e,"d => Symbol(d)",void 0,n.description?e.newString(n.description):e.undefined)}function ae(n,e){return n instanceof Date?y(e,"d => new Date(d)",void 0,e.newNumber(n.getTime())):void 0}function fe(n,e){if(n instanceof ArrayBuffer)return e.newArrayBuffer(n.slice(0));if(ArrayBuffer.isView(n)){const t=new Uint8Array(n.buffer,n.byteOffset,n.byteLength).slice();return z([e.newArrayBuffer(t.buffer),e.newString(n.constructor.name)],([r,s])=>y(e,"(buf, name) => new globalThis[name](buf)",void 0,r,s))}}const ce=[ue,ae,fe];function $(n){return typeof n=="function"&&/^class\s/.test(Function.prototype.toString.call(n))}function E(n){return typeof n=="function"||typeof n=="object"&&n!==null}function N(n,e){const t=new Set,r=s=>{if(!(!E(s)||t.has(s)||(e==null?void 0:e(s,t))===!1)){if(t.add(s),Array.isArray(s)){for(const i of s)r(i);return}if(typeof s=="object"){const i=Object.getPrototypeOf(s);i&&i!==Object.prototype&&r(i)}for(const i of Object.values(Object.getOwnPropertyDescriptors(s)))"value"in i&&r(i.value),"get"in i&&r(i.get),"set"in i&&r(i.set)}};return r(n),t}function le(n,e){return N(n,e?(t,r)=>r.size<e:void 0).size}function pe(){let n=()=>{},e=()=>{};return{promise:new Promise((r,s)=>{n=r,e=s}),resolve:n,reject:e}}function L(n,e,t,r){const s=n.newObject(),i=(o,u)=>{const a=r(o),f=typeof u.value=="undefined"?void 0:r(u.value),d=typeof u.get=="undefined"?void 0:r(u.get),h=typeof u.set=="undefined"?void 0:r(u.set);n.newObject().consume(_=>{Object.entries(u).forEach(([c,l])=>{const b=c==="value"?f:c==="get"?d:c==="set"?h:l?n.true:n.false;b&&n.setProp(_,c,b)}),n.setProp(s,a,_)})};try{const o=Object.getOwnPropertyDescriptors(e);Object.entries(o).forEach(([u,a])=>i(u,a)),Object.getOwnPropertySymbols(o).forEach(u=>i(u,o[u])),y(n,"Object.defineProperties",void 0,t,s).dispose()}finally{s.dispose()}}function de(n,e,t,r,s,i){var a;if(typeof e!="function")return;const o=n.newFunction(e.name,function(...f){const d=r(this),h=f.map(_=>r(_));if($(e)&&E(d)){const _=new e(...h);return Object.entries(_).forEach(([c,l])=>{n.setProp(this,c,t(l))}),this}return t(i?i(e,d,h):e.apply(d,h))}).consume(f=>y(n,`Cls => {
8
+ })`))}disposeEx(){this.fnGenerator.dispose(),this.fn.dispose()}}const A=[[Symbol,"Symbol"],[Symbol.prototype,"Symbol.prototype"],[Object,"Object"],[Object.prototype,"Object.prototype"],[Function,"Function"],[Function.prototype,"Function.prototype"],[Boolean,"Boolean"],[Boolean.prototype,"Boolean.prototype"],[Array,"Array"],[Array.prototype,"Array.prototype"],[Error,"Error"],[Error.prototype,"Error.prototype"],[EvalError,"EvalError"],[EvalError.prototype,"EvalError.prototype"],[RangeError,"RangeError"],[RangeError.prototype,"RangeError.prototype"],[ReferenceError,"ReferenceError"],[ReferenceError.prototype,"ReferenceError.prototype"],[SyntaxError,"SyntaxError"],[SyntaxError.prototype,"SyntaxError.prototype"],[TypeError,"TypeError"],[TypeError.prototype,"TypeError.prototype"],[URIError,"URIError"],[URIError.prototype,"URIError.prototype"],...Object.getOwnPropertyNames(Symbol).filter(n=>typeof Symbol[n]=="symbol").map(n=>[Symbol[n],`Symbol.${n}`])];function k(n,e){if("error"in e&&e.error){const{error:t}=e;let r;try{r=n.dump(t)}catch(i){}finally{t.alive&&t.dispose()}const s=new Error(typeof r=="object"&&r&&"message"in r?String(r.message):r!==void 0?String(r):"quickjs-emscripten-sync: VM evaluation failed");throw typeof r=="object"&&r&&("name"in r&&(s.name=String(r.name)),"stack"in r&&(s.stack=String(r.stack))),s}return e.value}function I(n,e){const t=k(n,n.evalCode(e)),r=(i,...o)=>k(n,n.callFunction(t,i!=null?i:n.undefined,...o)),s=()=>t.dispose();return r.dispose=s,r[Symbol.dispose]=s,Object.defineProperty(r,"alive",{get:()=>t.alive}),r}const R=new WeakMap;function C(n){R.has(n)||R.set(n,new Map)}function O(n){const e=R.get(n);if(e){for(const t of e.values())t.alive&&t.dispose();R.delete(n)}}function h(n,e,t,...r){const s=R.get(n);if(!s){const o=I(n,e);try{return o(t,...r)}finally{o.dispose()}}let i=s.get(e);return(!i||!i.alive)&&(i=k(n,n.evalCode(e)),s.set(e,i)),k(n,n.callFunction(i,t!=null?t:n.undefined,...r))}function re(n,e,t){return n.dump(h(n,"(a, b) => a instanceof b",void 0,e,t))}function W(n,e){const t=n.typeof(e);return t==="function"||t==="object"&&!n.sameValue(e,n.null)}function z(n,e){const t=JSON.stringify(e);return t?n.newString(t).consume(r=>h(n,"JSON.parse",void 0,r)):n.undefined}function P(n,e){try{return e(n)}finally{n.alive&&n.dispose()}}function $(n,e){try{return e(n)}finally{for(const t of n)t.alive&&t.dispose()}}function se([n,e],t){try{return t(n)}finally{e&&n.dispose()}}function B(n,e){try{return e(...n.map(t=>t[0]))}finally{for(const[t,r]of n)r&&t.dispose()}}function ie(n){return"handle"in n}function N(n){return ie(n)?n.handle:n}function oe(n,e,t,r){var i;let s;for(const o of r)if(s=o(e,n),s)break;return s?(i=t(e,s))!=null?i:s:void 0}function ue(n,e){return typeof n!="symbol"?void 0:h(e,"d => Symbol(d)",void 0,n.description?e.newString(n.description):e.undefined)}function ae(n,e){return n instanceof Date?h(e,"d => new Date(d)",void 0,e.newNumber(n.getTime())):void 0}function fe(n,e){if(n instanceof ArrayBuffer)return e.newArrayBuffer(n.slice(0));if(ArrayBuffer.isView(n)){const t=new Uint8Array(n.buffer,n.byteOffset,n.byteLength).slice();return $([e.newArrayBuffer(t.buffer),e.newString(n.constructor.name)],([r,s])=>h(e,"(buf, name) => new globalThis[name](buf)",void 0,r,s))}}const ce=[ue,ae,fe];function L(n){return typeof n=="function"&&/^class\s/.test(Function.prototype.toString.call(n))}function H(n){return typeof n=="function"||typeof n=="object"&&n!==null}function D(n,e){const t=new Set,r=s=>{if(!(!H(s)||t.has(s)||(e==null?void 0:e(s,t))===!1)){if(t.add(s),Array.isArray(s)){for(const i of s)r(i);return}if(typeof s=="object"){const i=Object.getPrototypeOf(s);i&&i!==Object.prototype&&r(i)}for(const i of Object.values(Object.getOwnPropertyDescriptors(s)))"value"in i&&r(i.value),"get"in i&&r(i.get),"set"in i&&r(i.set)}};return r(n),t}function le(n,e){return D(n,e?(t,r)=>r.size<e:void 0).size}function pe(){let n=()=>{},e=()=>{};return{promise:new Promise((r,s)=>{n=r,e=s}),resolve:n,reject:e}}function K(n,e,t,r,s=()=>{}){const i=n.newObject(),o=[],f=(a,u)=>{const l=r(a),y=typeof u.value=="undefined"?void 0:r(u.value),m=typeof u.get=="undefined"?void 0:r(u.get),c=typeof u.set=="undefined"?void 0:r(u.set);y&&o.push(y),m&&o.push(m),c&&o.push(c),n.newObject().consume(d=>{Object.entries(u).forEach(([v,w])=>{const j=v==="value"?y:v==="get"?m:v==="set"?c:w?n.true:n.false;j&&n.setProp(d,v,j)}),n.setProp(i,l,d)})};try{const a=Object.getOwnPropertyDescriptors(e);Object.entries(a).forEach(([u,l])=>f(u,l)),Object.getOwnPropertySymbols(a).forEach(u=>f(u,a[u])),h(n,"Object.defineProperties",void 0,t,i).dispose();for(const u of o)s(u)}finally{i.dispose()}}function de(n,e,t,r,s,i,o=()=>{}){var u;if(typeof e!="function")return;const f=n.newFunction(e.name,function(...l){const y=r(this),m=l.map(c=>r(c));if(L(e)&&H(y)){const c=new e(...m);return Object.entries(c).forEach(([d,v])=>{const w=t(v);n.setProp(this,d,w),o(w)}),this}return t(i?i(e,y,m):e.apply(y,m))}).consume(l=>h(n,`Cls => {
9
9
  const fn = function(...args) { return Cls.apply(this, args); };
10
10
  fn.name = Cls.name;
11
11
  fn.length = Cls.length;
12
12
  return fn;
13
- }`,void 0,f)),u=(a=s(e,o))!=null?a:o;return L(n,e,o,t),u}function ye(n,e,t){if(!(typeof e!="object"&&typeof e!="function")&&e!==null)return t(e,n.newHostRef(e).handle)}function he(n,e,t){var i;const r=W(n,e);return(i=t(e,r))!=null?i:r}function me(n,e,t,r){var s,i;if(e instanceof Map){const o=y(n,"() => new Map()"),u=(s=r(e,o))!=null?s:o;for(const[a,f]of e)y(n,"(m, k, v) => m.set(k, v)",void 0,o,t(a),t(f)).dispose();return u}if(e instanceof Set){const o=y(n,"() => new Set()"),u=(i=r(e,o))!=null?i:o;for(const a of e)y(n,"(s, v) => s.add(v)",void 0,o,t(a)).dispose();return u}}function _e(n,e,t,r){var a;if(typeof e!="object"||e===null)return;const s=Array.isArray(e)?n.newArray():n.newObject(),i=(a=r(e,s))!=null?a:s,o=Object.getPrototypeOf(e),u=o&&o!==Object.prototype&&o!==Array.prototype?t(o):void 0;return u&&y(n,"Object.setPrototypeOf",void 0,i,u).dispose(),L(n,e,s,t),i}function ve(n,e){switch(typeof e){case"undefined":return n.undefined;case"number":return n.newNumber(e);case"string":return n.newString(e);case"boolean":return e?n.true:n.false;case"bigint":return n.newBigInt(e);case"object":return e===null?n.null:void 0}}function be(n,e,t,r){var i;if(!(e instanceof Promise))return;const s=n.newPromise();return e.then(o=>s.resolve(t(o)),o=>s.reject(t(o))),(i=r(e,s))!=null?i:s.handle}function D(n,e){var d,h,_,c,l,b,j;const{ctx:t,unmarshal:r,isMarshalable:s,find:i,pre:o}=e;{const v=ve(t,n);if(v)return v}{const v=i(n);if(v)return v}if((d=e.marshalByReference)!=null&&d.call(e,n)&&e.registerHostRef){const v=ye(t,n,e.registerHostRef);if(v)return v}const u=s==null?void 0:s(n);if(u===!1)return t.undefined;const a=(v,P)=>o(v,P,u);if(u==="json")return he(t,n,a);const f=v=>D(v,e);return(j=(b=(l=(c=(_=oe(t,n,a,[...ce,...(h=e.custom)!=null?h:[]]))!=null?_:be(t,n,f,a))!=null?c:de(t,n,f,r,a,e.preApply))!=null?l:me(t,n,f,a))!=null?b:_e(t,n,f,a))!=null?j:t.undefined}function we(n,e,t,r){var i;let s;for(const o of r)if(s=o(e,n),s)break;return s?(i=t(s,e))!=null?i:s:void 0}function ge(n,e){if(e.typeof(n)!=="symbol")return;const t=e.getString(e.getProp(n,"description"));return Symbol(t)}function je(n,e){if(!S(y(e,"a => a instanceof Date",void 0,n),r=>e.dump(r)))return;const t=S(y(e,"a => a.getTime()",void 0,n),r=>e.getNumber(r));return new Date(t)}function Se(n,e){if(S(y(e,"a => a instanceof ArrayBuffer",void 0,n),t=>e.dump(t))){const t=e.getArrayBuffer(n),r=t.value.slice();return t.dispose(),r.buffer}if(S(y(e,"a => ArrayBuffer.isView(a)",void 0,n),t=>e.dump(t))){const t=S(y(e,"a => a.constructor.name",void 0,n),u=>e.getString(u)),r=globalThis[t];if(typeof r!="function")return;const s=y(e,"a => a.buffer.slice(a.byteOffset, a.byteOffset + a.byteLength)",void 0,n),i=e.getArrayBuffer(s),o=i.value.slice();return i.dispose(),s.dispose(),new r(o.buffer)}}const Pe=[ge,je,Se];function K(n,e,t,r){S(n.newFunction("",(s,i)=>{const[o]=r(s);if(typeof o!="string"&&typeof o!="number"&&typeof o!="symbol")return;const u=[["value",!0],["get",!0],["set",!0],["configurable",!1],["enumerable",!1],["writable",!1]].reduce((a,[f,d])=>{const h=n.getProp(i,f),_=n.typeof(h);if(_==="undefined")return a;if(!d&&_==="boolean")return a[f]=n.dump(n.getProp(i,f)),a;const[c,l]=r(h);return l&&h.dispose(),a[f]=c,a},{});Object.defineProperty(t,o,u)}),s=>{y(n,`(o, fn) => {
13
+ }`,void 0,l)),a=(u=s(e,f))!=null?u:f;return K(n,e,f,t,o),a}function ye(n,e,t){if(!(typeof e!="object"&&typeof e!="function")&&e!==null)return t(e,n.newHostRef(e).handle)}function he(n,e,t){var i;const r=z(n,e);return(i=t(e,r))!=null?i:r}function me(n,e,t,r,s=()=>{}){var i,o;if(e instanceof Map){const f=h(n,"() => new Map()"),a=(i=r(e,f))!=null?i:f;for(const[u,l]of e){const y=t(u),m=t(l);h(n,"(m, k, v) => m.set(k, v)",void 0,f,y,m).dispose(),s(y),s(m)}return a}if(e instanceof Set){const f=h(n,"() => new Set()"),a=(o=r(e,f))!=null?o:f;for(const u of e){const l=t(u);h(n,"(s, v) => s.add(v)",void 0,f,l).dispose(),s(l)}return a}}function _e(n,e,t,r,s=()=>{}){var u;if(typeof e!="object"||e===null)return;const i=Array.isArray(e)?n.newArray():n.newObject(),o=(u=r(e,i))!=null?u:i,f=Object.getPrototypeOf(e),a=f&&f!==Object.prototype&&f!==Array.prototype?t(f):void 0;return a&&(h(n,"Object.setPrototypeOf",void 0,o,a).dispose(),s(a)),K(n,e,i,t,s),o}function ve(n,e){switch(typeof e){case"undefined":return n.undefined;case"number":return n.newNumber(e);case"string":return n.newString(e);case"boolean":return e?n.true:n.false;case"bigint":return n.newBigInt(e);case"object":return e===null?n.null:void 0}}function be(n,e,t,r){var i;if(!(e instanceof Promise))return;const s=n.newPromise();return e.then(o=>s.resolve(t(o)),o=>s.reject(t(o))),(i=r(e,s))!=null?i:s.handle}function U(n,e){var y,m,c,d,v,w,j,T;const{ctx:t,unmarshal:r,isMarshalable:s,find:i,pre:o}=e;{const S=ve(t,n);if(S)return typeof n=="bigint"&&((y=e.registerTransient)==null||y.call(e,S)),S}{const S=i(n);if(S)return S}if((m=e.marshalByReference)!=null&&m.call(e,n)&&e.registerHostRef){const S=ye(t,n,e.registerHostRef);if(S)return S}const f=s==null?void 0:s(n);if(f===!1)return t.undefined;const a=(S,M)=>o(S,M,f);if(f==="json")return he(t,n,a);const u=S=>U(S,e),l=e.disposeTransient;return(T=(j=(w=(v=(d=oe(t,n,a,[...ce,...(c=e.custom)!=null?c:[]]))!=null?d:be(t,n,u,a))!=null?v:de(t,n,u,r,a,e.preApply,l))!=null?w:me(t,n,u,a,l))!=null?j:_e(t,n,u,a,l))!=null?T:t.undefined}function we(n,e,t,r){var i;let s;for(const o of r)if(s=o(e,n),s)break;return s?(i=t(s,e))!=null?i:s:void 0}function ge(n,e){if(e.typeof(n)!=="symbol")return;const t=e.getString(e.getProp(n,"description"));return Symbol(t)}function je(n,e){if(!P(h(e,"a => a instanceof Date",void 0,n),r=>e.dump(r)))return;const t=P(h(e,"a => a.getTime()",void 0,n),r=>e.getNumber(r));return new Date(t)}function Se(n,e){if(P(h(e,"a => a instanceof ArrayBuffer",void 0,n),t=>e.dump(t))){const t=e.getArrayBuffer(n),r=t.value.slice();return t.dispose(),r.buffer}if(P(h(e,"a => ArrayBuffer.isView(a)",void 0,n),t=>e.dump(t))){const t=P(h(e,"a => a.constructor.name",void 0,n),f=>e.getString(f)),r=globalThis[t];if(typeof r!="function")return;const s=h(e,"a => a.buffer.slice(a.byteOffset, a.byteOffset + a.byteLength)",void 0,n),i=e.getArrayBuffer(s),o=i.value.slice();return i.dispose(),s.dispose(),new r(o.buffer)}}const Pe=[ge,je,Se];function Q(n,e,t,r){P(n.newFunction("",(s,i)=>{const[o]=r(s);if(typeof o!="string"&&typeof o!="number"&&typeof o!="symbol")return;const f=[["value",!0],["get",!0],["set",!0],["configurable",!1],["enumerable",!1],["writable",!1]].reduce((a,[u,l])=>{const y=n.getProp(i,u),m=n.typeof(y);if(m==="undefined")return a;if(!l&&m==="boolean")return a[u]=n.dump(n.getProp(i,u)),a;const[c,d]=r(y);return d&&y.dispose(),a[u]=c,a},{});Object.defineProperty(t,o,f)}),s=>{h(n,`(o, fn) => {
14
14
  const descs = Object.getOwnPropertyDescriptors(o);
15
15
  Object.entries(descs).forEach(([k, v]) => fn(k, v));
16
16
  Object.getOwnPropertySymbols(descs).forEach(k => fn(k, descs[k]));
17
- }`,void 0,e,s).dispose()})}function ke(n,e,t,r,s){var u;if(n.typeof(e)!=="function")return;const i=function(...a){return C([t(this),...a.map(f=>t(f))],(f,...d)=>{if(new.target){const[l]=r(y(n,"(Cls, ...args) => new Cls(...args)",f,e,...d));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(l)),this}const h=k(n,n.callFunction(e,f,...d)),[_,c]=r(h);return c&&h.dispose(),_})},o=(u=s(i,e))!=null?u:i;return K(n,e,i,r),o}function Q(n,e){const t=n.toHostRef(e);if(t)try{return{value:t.value}}finally{t.dispose()}}function Oe(n,e,t,r){const s=S(y(n,"a => a instanceof Map",void 0,e),a=>n.dump(a)),i=!s&&S(y(n,"a => a instanceof Set",void 0,e),a=>n.dump(a));if(!s&&!i)return;const o=s?new Map:new Set;r(o,e);const u=n.unwrapResult(n.getIterator(e));try{for(const a of u){const f=n.unwrapResult(a);if(s){const d=n.getProp(f,0),h=n.getProp(f,1),[_,c]=t(d),[l,b]=t(h);c&&d.dispose(),b&&h.dispose(),o.set(_,l),f.dispose()}else{const[d,h]=t(f);h&&f.dispose(),o.add(d)}}}finally{u.alive&&u.dispose()}return o}function Ee(n,e,t,r){var u;if(n.typeof(e)!=="object"||n.sameValue(e,n.null))return;const s=S(y(n,"Array.isArray",void 0,e),a=>n.dump(a))?[]:{},i=(u=r(s,e))!=null?u:s,o=S(y(n,`o => {
17
+ }`,void 0,e,s).dispose()})}function Te(n,e,t,r,s){var f;if(n.typeof(e)!=="function")return;const i=function(...a){return B([t(this),...a.map(u=>t(u))],(u,...l)=>{if(new.target){const[d]=r(h(n,"(Cls, ...args) => new Cls(...args)",u,e,...l));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(d)),this}const y=k(n,n.callFunction(e,u,...l)),[m,c]=r(y);return c&&y.dispose(),m})},o=(f=s(i,e))!=null?f:i;return Q(n,e,i,r),o}function q(n,e){const t=n.toHostRef(e);if(t)try{return{value:t.value}}finally{t.dispose()}}function ke(n,e,t,r){const s=P(h(n,"a => a instanceof Map",void 0,e),a=>n.dump(a)),i=!s&&P(h(n,"a => a instanceof Set",void 0,e),a=>n.dump(a));if(!s&&!i)return;const o=s?new Map:new Set;r(o,e);const f=n.unwrapResult(n.getIterator(e));try{for(const a of f){const u=n.unwrapResult(a);if(s){const l=n.getProp(u,0),y=n.getProp(u,1),[m,c]=t(l),[d,v]=t(y);c&&l.dispose(),v&&y.dispose(),o.set(m,d),u.dispose()}else{const[l,y]=t(u);y&&u.dispose(),o.add(l)}}}finally{f.alive&&f.dispose()}return o}function Oe(n,e,t,r){var f;if(n.typeof(e)!=="object"||n.sameValue(e,n.null))return;const s=P(h(n,"Array.isArray",void 0,e),a=>n.dump(a))?[]:{},i=(f=r(s,e))!=null?f:s,o=P(h(n,`o => {
18
18
  const p = Object.getPrototypeOf(o);
19
19
  return !p || p === Object.prototype || p === Array.prototype ? undefined : p;
20
- }`,void 0,e),a=>{if(n.typeof(a)==="undefined")return;const[f]=t(a);return f});return typeof o=="object"&&Object.setPrototypeOf(i,o),K(n,e,s,t),i}function Re(n,e){const t=n.typeof(e);return t==="undefined"||t==="number"||t==="string"||t==="boolean"?[n.dump(e),!0]:t==="bigint"?[n.getBigInt(e),!0]:t==="object"&&n.sameValue(e,n.null)?[null,!0]:[void 0,!1]}function Te(n,e,t,r){var f;if(!He(n,e))return;const s=pe(),[i,o]=t(s.resolve),[u,a]=t(s.reject);return y(n,"(p, res, rej) => { p.then(res, rej); }",void 0,e,i,u),o&&i.dispose(),a&&u.dispose(),(f=r(s.promise,e))!=null?f:s.promise}function He(n,e){return e.owner?n.unwrapResult(n.evalCode("Promise")).consume(t=>e.owner?ne(n,e,t):!1):!1}function q(n,e){const[t]=X(n,e);return t}function X(n,e){var d,h,_;const{ctx:t,marshal:r,find:s,pre:i}=e;{const[c,l]=Re(t,n);if(l)return[c,!1]}{const c=s(n);if(c)return[c,!0]}const o=c=>X(c,e);if(e.hostRef){const c=Q(t,n);if(c)return[c.value,!0]}const u=we(t,n,i,[...Pe,...(d=e.custom)!=null?d:[]]);if(u)return[u,!0];const a=Oe(t,n,o,i);return a?[a,!0]:[(_=(h=Te(t,n,r,i))!=null?h:ke(t,n,r,o,i))!=null?_:Ee(t,n,o,i),!1]}class U{constructor(e){p(this,"ctx");p(this,"_keyToId",new Map);p(this,"_key2ToId",new Map);p(this,"_idToHandle",new Map);p(this,"_idToHandle2",new Map);p(this,"_idToKey",new Map);p(this,"_idToKey2",new Map);p(this,"_disposables",new Set);p(this,"_mapGet");p(this,"_mapSet");p(this,"_mapDelete");p(this,"_mapClear");p(this,"_nextId",Number.MIN_SAFE_INTEGER);this.ctx=e;const t=e.unwrapResult(e.evalCode(`() => {
20
+ }`,void 0,e),a=>{if(n.typeof(a)==="undefined")return;const[u]=t(a);return u});return typeof o=="object"&&Object.setPrototypeOf(i,o),Q(n,e,s,t),i}function He(n,e){const t=n.typeof(e);return t==="undefined"||t==="number"||t==="string"||t==="boolean"?[n.dump(e),!0]:t==="bigint"?[n.getBigInt(e),!0]:t==="object"&&n.sameValue(e,n.null)?[null,!0]:[void 0,!1]}function Ee(n,e,t,r){var u;if(!Re(n,e))return;const s=pe(),[i,o]=t(s.resolve),[f,a]=t(s.reject);return h(n,"(p, res, rej) => { p.then(res, rej); }",void 0,e,i,f),o&&i.dispose(),a&&f.dispose(),(u=r(s.promise,e))!=null?u:s.promise}function Re(n,e){return e.owner?n.unwrapResult(n.evalCode("Promise")).consume(t=>e.owner?re(n,e,t):!1):!1}function X(n,e){const[t]=Y(n,e);return t}function Y(n,e){var l,y,m;const{ctx:t,marshal:r,find:s,pre:i}=e;{const[c,d]=He(t,n);if(d)return[c,!1]}{const c=s(n);if(c)return[c,!0]}const o=c=>Y(c,e);if(e.hostRef){const c=q(t,n);if(c)return[c.value,!0]}const f=we(t,n,i,[...Pe,...(l=e.custom)!=null?l:[]]);if(f)return[f,!0];const a=ke(t,n,o,i);return a?[a,!0]:[(m=(y=Ee(t,n,r,i))!=null?y:Te(t,n,r,o,i))!=null?m:Oe(t,n,o,i),!1]}class V{constructor(e){p(this,"ctx");p(this,"_keyToId",new Map);p(this,"_key2ToId",new Map);p(this,"_idToHandle",new Map);p(this,"_idToHandle2",new Map);p(this,"_idToKey",new Map);p(this,"_idToKey2",new Map);p(this,"_disposables",new Set);p(this,"_mapGet");p(this,"_mapSet");p(this,"_mapDelete");p(this,"_mapClear");p(this,"_nextId",Number.MIN_SAFE_INTEGER);this.ctx=e;const t=e.unwrapResult(e.evalCode(`() => {
21
21
  const mapSym = new Map();
22
22
  let map = new WeakMap();
23
23
  let map2 = new WeakMap();
@@ -40,7 +40,7 @@
40
40
  map2 = new WeakMap();
41
41
  }
42
42
  };
43
- }`)).consume(r=>this._call(r,void 0));this._mapGet=e.getProp(t,"get"),this._mapSet=e.getProp(t,"set"),this._mapDelete=e.getProp(t,"delete"),this._mapClear=e.getProp(t,"clear"),t.dispose(),this._disposables.add(this._mapGet),this._disposables.add(this._mapSet),this._disposables.add(this._mapDelete),this._disposables.add(this._mapClear)}set(e,t,r,s){var u;if(!t.alive||s&&!s.alive)return!1;const i=(u=this.get(e))!=null?u:this.get(r);if(i)return i===t||i===s;const o=this._nextId++;return this._keyToId.set(e,o),this._idToHandle.set(o,t),this._idToKey.set(o,e),r&&(this._key2ToId.set(r,o),this._idToKey2.set(o,r),s&&this._idToHandle2.set(o,s)),this.ctx.newNumber(o).consume(a=>{this._call(this._mapSet,void 0,t,a,s!=null?s:this.ctx.undefined)}),!0}merge(e){if(e)for(const t of e)t&&t[1]&&this.set(t[0],t[1],t[2],t[3])}get(e){var s;const t=(s=this._keyToId.get(e))!=null?s:this._key2ToId.get(e),r=typeof t=="number"?this._idToHandle.get(t):void 0;if(r){if(!r.alive){this.delete(e);return}return r}}getByHandle(e){if(e.alive)return this._idToKey.get(this.ctx.getNumber(this._call(this._mapGet,void 0,e)))}has(e){return!!this.get(e)}hasHandle(e){return typeof this.getByHandle(e)!="undefined"}keys(){return this._keyToId.keys()}delete(e,t){var a;const r=(a=this._keyToId.get(e))!=null?a:this._key2ToId.get(e);if(typeof r=="undefined")return;const s=this._idToHandle.get(r),i=this._idToHandle2.get(r);this._call(this._mapDelete,void 0,...[s,i].filter(f=>!!(f!=null&&f.alive)));const o=this._idToKey.get(r),u=this._idToKey2.get(r);typeof o!="undefined"&&this._keyToId.delete(o),typeof u!="undefined"&&this._key2ToId.delete(u),this._idToHandle.delete(r),this._idToHandle2.delete(r),this._idToKey.delete(r),this._idToKey2.delete(r),t&&(s!=null&&s.alive&&s.dispose(),i!=null&&i.alive&&i.dispose())}deleteByHandle(e,t){const r=this.getByHandle(e);typeof r!="undefined"&&this.delete(r,t)}clear(){this._nextId=0,this._keyToId.clear(),this._key2ToId.clear(),this._idToHandle.clear(),this._idToHandle2.clear(),this._idToKey.clear(),this._idToKey2.clear(),this._mapClear.alive&&this._call(this._mapClear,void 0)}dispose(){for(const e of this._disposables.values())e.alive&&e.dispose();for(const e of this._idToHandle.values())e.alive&&e.dispose();for(const e of this._idToHandle2.values())e.alive&&e.dispose();this._disposables.clear(),this.clear()}get size(){return this._keyToId.size}[Symbol.iterator](){const e=this._keyToId.keys();return{next:()=>{for(;;){const t=e.next();if(t.done)return{value:void 0,done:!0};const r=this._keyToId.get(t.value);if(typeof r=="undefined")continue;const s=this._idToHandle.get(r),i=this._idToHandle2.get(r);if(!s)continue;const o=this._idToKey2.get(r);return{value:[t.value,s,o,i],done:!1}}}}}_call(e,t,...r){return k(this.ctx,this.ctx.callFunction(e,typeof t=="undefined"?this.ctx.undefined:t,...r))}}function Me(n,e,t,r,s,i,o,u=!0){if(!E(e)||e instanceof Promise||e instanceof Date||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||e instanceof Map||e instanceof Set||o&&!o(e))return;if(Ae(e,t)||!u)return e;const a=new Proxy(e,{get(f,d){return d===t?f:Reflect.get(f,d)},set(f,d,h,_){var b;const c=R(h,t),l=(b=i==null?void 0:i(_))!=null?b:"host";return l!=="vm"&&!Reflect.set(f,d,c)||l==="host"||!n.alive||C([s(_),s(d),s(c)],(j,v,P)=>{const[B,F]=A(n,j,r);F?B.consume(V=>n.setProp(V,v,P)):n.setProp(B,v,P)}),!0},deleteProperty(f,d){var _;const h=(_=i==null?void 0:i(a))!=null?_:"host";return C([s(a),s(d)],(c,l)=>{const[b,j]=A(n,c,r);if(h==="vm"||Reflect.deleteProperty(f,d)){if(h==="host"||!n.alive)return!0;j?b.consume(v=>y(n,"(a, b) => delete a[b]",void 0,v,l)):y(n,"(a, b) => delete a[b]",void 0,b,l)}return!0})},defineProperty(f,d,h){var l;const _=(l=i==null?void 0:i(a))!=null?l:"host",c=ee({},h);return"value"in c&&(c.value=R(c.value,t)),typeof c.get=="function"&&(c.get=R(c.get,t)),typeof c.set=="function"&&(c.set=R(c.set,t)),_!=="vm"&&!Reflect.defineProperty(f,d,c)?!1:(_==="host"||!n.alive||C([s(a),s(d),s(c)],(b,j,v)=>{const[P,B]=A(n,b,r),F=V=>y(n,"(o, k, d) => { Object.defineProperty(o, k, d); }",void 0,V,j,v).dispose();B?P.consume(F):F(P)}),!0)}});return a}function Ce(n,e,t,r,s,i,o,u=!0){if(!J(n,e)||o&&!o(e,n))return[void 0,!1];if(Y(n,e,r))return[e,!1];if(!u)return[e,!1];const a=c=>{const l=i==null?void 0:i(s(c));return typeof l=="string"?n.newString(l):n.undefined},f=(c,l,b)=>{const j=s(c);if(!j)return;const v=s(l);if(v==="__proto__")return;const P=s(b);R(j,t)[v]=P},d=(c,l)=>{const b=s(c);if(!b)return;const j=s(l);Reflect.deleteProperty(R(b,t),j)},h=(c,l,b)=>{const j=s(c);if(!j)return;const v=s(l);if(v==="__proto__")return;const P=s(b);Object.defineProperty(R(j,t),v,P)},_=n.newFunction("proxyFuncs",(c,...l)=>{switch(n.getNumber(c)){case 1:return a(l[0]);case 2:return f(l[0],l[1],l[2]);case 3:return d(l[0],l[1]);case 4:return h(l[0],l[1],l[2])}return n.undefined});return S(_,c=>[y(n,`(target, sym, proxyFuncs) => {
43
+ }`)).consume(r=>this._call(r,void 0));this._mapGet=e.getProp(t,"get"),this._mapSet=e.getProp(t,"set"),this._mapDelete=e.getProp(t,"delete"),this._mapClear=e.getProp(t,"clear"),t.dispose(),this._disposables.add(this._mapGet),this._disposables.add(this._mapSet),this._disposables.add(this._mapDelete),this._disposables.add(this._mapClear)}set(e,t,r,s){var f;if(!t.alive||s&&!s.alive)return!1;const i=(f=this.get(e))!=null?f:this.get(r);if(i)return i===t||i===s;const o=this._nextId++;return this._keyToId.set(e,o),this._idToHandle.set(o,t),this._idToKey.set(o,e),r&&(this._key2ToId.set(r,o),this._idToKey2.set(o,r),s&&this._idToHandle2.set(o,s)),this.ctx.newNumber(o).consume(a=>{this._call(this._mapSet,void 0,t,a,s!=null?s:this.ctx.undefined)}),!0}merge(e){if(e)for(const t of e)t&&t[1]&&this.set(t[0],t[1],t[2],t[3])}get(e){var s;const t=(s=this._keyToId.get(e))!=null?s:this._key2ToId.get(e),r=typeof t=="number"?this._idToHandle.get(t):void 0;if(r){if(!r.alive){this.delete(e);return}return r}}getByHandle(e){if(e.alive)return this._idToKey.get(this.ctx.getNumber(this._call(this._mapGet,void 0,e)))}has(e){return!!this.get(e)}hasHandle(e){return typeof this.getByHandle(e)!="undefined"}keys(){return this._keyToId.keys()}delete(e,t){var a;const r=(a=this._keyToId.get(e))!=null?a:this._key2ToId.get(e);if(typeof r=="undefined")return;const s=this._idToHandle.get(r),i=this._idToHandle2.get(r);this._call(this._mapDelete,void 0,...[s,i].filter(u=>!!(u!=null&&u.alive)));const o=this._idToKey.get(r),f=this._idToKey2.get(r);typeof o!="undefined"&&this._keyToId.delete(o),typeof f!="undefined"&&this._key2ToId.delete(f),this._idToHandle.delete(r),this._idToHandle2.delete(r),this._idToKey.delete(r),this._idToKey2.delete(r),t&&(s!=null&&s.alive&&s.dispose(),i!=null&&i.alive&&i.dispose())}deleteByHandle(e,t){const r=this.getByHandle(e);typeof r!="undefined"&&this.delete(r,t)}clear(){this._nextId=0,this._keyToId.clear(),this._key2ToId.clear(),this._idToHandle.clear(),this._idToHandle2.clear(),this._idToKey.clear(),this._idToKey2.clear(),this._mapClear.alive&&this._call(this._mapClear,void 0)}dispose(){for(const e of this._disposables.values())e.alive&&e.dispose();for(const e of this._idToHandle.values())e.alive&&e.dispose();for(const e of this._idToHandle2.values())e.alive&&e.dispose();this._disposables.clear(),this.clear()}get size(){return this._keyToId.size}[Symbol.iterator](){const e=this._keyToId.keys();return{next:()=>{for(;;){const t=e.next();if(t.done)return{value:void 0,done:!0};const r=this._keyToId.get(t.value);if(typeof r=="undefined")continue;const s=this._idToHandle.get(r),i=this._idToHandle2.get(r);if(!s)continue;const o=this._idToKey2.get(r);return{value:[t.value,s,o,i],done:!1}}}}}_call(e,t,...r){return k(this.ctx,this.ctx.callFunction(e,typeof t=="undefined"?this.ctx.undefined:t,...r))}}function Me(n,e,t,r,s,i,o,f=!0){if(!H(e)||e instanceof Promise||e instanceof Date||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||e instanceof Map||e instanceof Set||o&&!o(e))return;if(Ae(e,t)||!f)return e;const a=new Proxy(e,{get(u,l){return l===t?u:Reflect.get(u,l)},set(u,l,y,m){var v;const c=E(y,t),d=(v=i==null?void 0:i(m))!=null?v:"host";return d!=="vm"&&!Reflect.set(u,l,c)||d==="host"||!n.alive||B([s(m),s(l),s(c)],(w,j,T)=>{const[S,M]=F(n,w,r);M?S.consume(G=>n.setProp(G,j,T)):n.setProp(S,j,T)}),!0},deleteProperty(u,l){var m;const y=(m=i==null?void 0:i(a))!=null?m:"host";return B([s(a),s(l)],(c,d)=>{const[v,w]=F(n,c,r);if(y==="vm"||Reflect.deleteProperty(u,l)){if(y==="host"||!n.alive)return!0;w?v.consume(j=>h(n,"(a, b) => delete a[b]",void 0,j,d)):h(n,"(a, b) => delete a[b]",void 0,v,d)}return!0})},defineProperty(u,l,y){var d;const m=(d=i==null?void 0:i(a))!=null?d:"host",c=te({},y);return"value"in c&&(c.value=E(c.value,t)),typeof c.get=="function"&&(c.get=E(c.get,t)),typeof c.set=="function"&&(c.set=E(c.set,t)),m!=="vm"&&!Reflect.defineProperty(u,l,c)?!1:(m==="host"||!n.alive||B([s(a),s(l),s(c)],(v,w,j)=>{const[T,S]=F(n,v,r),M=G=>h(n,"(o, k, d) => { Object.defineProperty(o, k, d); }",void 0,G,w,j).dispose();S?T.consume(M):M(T)}),!0)}});return a}function Ce(n,e,t,r,s,i,o,f=!0){if(!W(n,e)||o&&!o(e,n))return[void 0,!1];if(Z(n,e,r))return[e,!1];if(!f)return[e,!1];const a=c=>{const d=i==null?void 0:i(s(c));return typeof d=="string"?n.newString(d):n.undefined},u=(c,d,v)=>{const w=s(c);if(!w)return;const j=s(d);if(j==="__proto__")return;const T=s(v);E(w,t)[j]=T},l=(c,d)=>{const v=s(c);if(!v)return;const w=s(d);Reflect.deleteProperty(E(v,t),w)},y=(c,d,v)=>{const w=s(c);if(!w)return;const j=s(d);if(j==="__proto__")return;const T=s(v);Object.defineProperty(E(w,t),j,T)},m=n.newFunction("proxyFuncs",(c,...d)=>{switch(n.getNumber(c)){case 1:return a(d[0]);case 2:return u(d[0],d[1],d[2]);case 3:return l(d[0],d[1]);case 4:return y(d[0],d[1],d[2])}return n.undefined});return P(m,c=>[h(n,`(target, sym, proxyFuncs) => {
44
44
  const rec = new Proxy(target, {
45
45
  get(obj, key, receiver) {
46
46
  return key === sym ? obj : Reflect.get(obj, key, receiver)
@@ -77,4 +77,4 @@
77
77
  },
78
78
  });
79
79
  return rec;
80
- }`,void 0,e,r,c),!0])}function R(n,e){var t;return E(n)&&(t=n[e])!=null?t:n}function A(n,e,t){return Y(n,e,t)?[n.getProp(e,t),!0]:[e,!1]}function Ae(n,e){return E(n)&&!!n[e]}function Y(n,e,t){return!!n.dump(y(n,'(a, s) => (a instanceof Promise) || (a instanceof Date) || (a instanceof ArrayBuffer) || (ArrayBuffer.isView(a)) || (a instanceof Map) || (a instanceof Set) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,t))}class Z{constructor(e,t){p(this,"context");p(this,"_map");p(this,"_registeredMap");p(this,"_registeredMapDispose",new Set);p(this,"_sync",new Set);p(this,"_temporalSync",new Set);p(this,"_symbol",Symbol());p(this,"_symbolHandle");p(this,"_options");p(this,"_isMarshalable",e=>{var r,s;const t=(r=this._options)==null?void 0:r.isMarshalable;return(s=typeof t=="function"?t(this._unwrap(e)):t)!=null?s:"json"});p(this,"_marshalByReference",e=>{var t,r;return!!((r=(t=this._options)==null?void 0:t.marshalByReference)!=null&&r.call(t,this._unwrap(e)))});p(this,"_registerHostRef",(e,t)=>{const r=this._unwrap(e),s=this._map.get(r);return s||(this._map.set(r,t),t)});p(this,"_marshalFind",e=>{var s,i,o;const t=this._unwrap(e);return(o=(i=(s=this._registeredMap.get(e))!=null?s:t!==e?this._registeredMap.get(t):void 0)!=null?i:this._map.get(e))!=null?o:t!==e?this._map.get(t):void 0});p(this,"_marshalPre",(e,t,r)=>{var s;if(r!=="json")return(s=this._register(e,ie(t),this._map))==null?void 0:s[1]});p(this,"_marshalPreApply",(e,t,r)=>{const s=E(t)?this._unwrap(t):void 0;s&&this._temporalSync.add(s);try{return e.apply(t,r)}finally{s&&this._temporalSync.delete(s)}});p(this,"_marshal",e=>{var o,u,a,f;const t=this._registeredMap.get(e);if(t)return[t,!1];const r=this._marshalByReference(e)?this._unwrap(e):(o=this._wrap(e))!=null?o:e,s=D(r,{ctx:this.context,unmarshal:this._unmarshal,isMarshalable:this._isMarshalable,marshalByReference:this._marshalByReference,registerHostRef:this._registerHostRef,find:this._marshalFind,pre:this._marshalPre,preApply:this._marshalPreApply,custom:(u=this._options)==null?void 0:u.customMarshaller}),i=(f=(a=this._options)==null?void 0:a.syncEnabled)!=null?f:!0;return[s,!i||!this._map.hasHandle(s)]});p(this,"_preUnmarshal",(e,t)=>{var r,s,i;return(i=this._register(e,t,void 0,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0))==null?void 0:i[0]});p(this,"_unmarshalFind",e=>{var t;return(t=this._registeredMap.getByHandle(e))!=null?t:this._map.getByHandle(e)});p(this,"_unmarshal",e=>{var s,i,o;const t=this._registeredMap.getByHandle(e);if(typeof t!="undefined")return t;if((s=this._options)!=null&&s.marshalByReference){const u=Q(this.context,e);if(u)return u.value}const[r]=this._wrapHandle(e);return q(r!=null?r:e,{ctx:this.context,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal,custom:(i=this._options)==null?void 0:i.customUnmarshaller,hostRef:!!((o=this._options)!=null&&o.marshalByReference)})});p(this,"_syncMode",e=>{const t=this._unwrap(e);return this._sync.has(t)||this._temporalSync.has(t)?"both":void 0});p(this,"_unwrapIfNotSynced",e=>{const t=this._unwrap(e);return t instanceof Promise||!this._sync.has(t)?t:e});var r;t!=null&&t.compat&&!("runtime"in e)&&(e.runtime={hasPendingJob:()=>e.hasPendingJob(),executePendingJobs:s=>e.executePendingJobs(s)}),this.context=t!=null&&t.experimentalContextEx?w(e):e,H(this.context),this._options=t,this._symbolHandle=e.unwrapResult(e.evalCode("Symbol()")),this._map=new U(e),this._registeredMap=new U(e),this.registerAll((r=t==null?void 0:t.registeredObjects)!=null?r:M)}dispose(){var e,t;this._map.dispose(),this._registeredMap.dispose(),this._symbolHandle.dispose(),O(this.context),(t=(e=this.context).disposeEx)==null||t.call(e)}[Symbol.dispose](){this.dispose()}evalCode(e){const t=this.context.evalCode(e);return this._unwrapResultAndUnmarshal(t)}evalModule(e,t="module.js"){const r=this.context.evalCode(e,t,{type:"module"});return this._unwrapResultAndUnmarshal(r)}executePendingJobs(e){const t=this.context.runtime.executePendingJobs(e);if("value"in t)return t.value;throw this._unwrapIfNotSynced(S(t.error,this._unmarshal))}setMemoryLimit(e){this.context.runtime.setMemoryLimit(e)}setMaxStackSize(e){this.context.runtime.setMaxStackSize(e)}getMemoryUsage(){const e=this.context.runtime.computeMemoryUsage();try{return this.context.dump(e)}finally{e.dispose()}}dumpMemoryUsage(){return this.context.runtime.dumpMemoryUsage()}expose(e){for(const[t,r]of Object.entries(e))re(this._marshal(r),s=>{this.context.setProp(this.context.global,t,s)})}sync(e){const t=this._wrap(e);return typeof t=="undefined"?e:(N(t,r=>{const s=this._unwrap(r);this._sync.add(s)}),t)}register(e,t){if(this._registeredMap.has(e))return;const r=typeof t=="string"?this._unwrapResult(this.context.evalCode(t)):t;this.context.sameValue(r,this.context.undefined)||(typeof t=="string"&&this._registeredMapDispose.add(e),this._registeredMap.set(e,r))}registerAll(e){for(const[t,r]of e)this.register(t,r)}unregister(e,t){this._registeredMap.delete(e,this._registeredMapDispose.has(e)||t),this._registeredMapDispose.delete(e)}unregisterAll(e,t){for(const r of e)this.unregister(r,t)}startSync(e){if(!E(e))return;const t=this._unwrap(e);this._sync.add(t)}endSync(e){this._sync.delete(this._unwrap(e))}_unwrapResult(e){if("value"in e)return e.value;throw this._unwrapIfNotSynced(S(e.error,this._unmarshal))}_unwrapResultAndUnmarshal(e){if(e)return this._unwrapIfNotSynced(S(this._unwrapResult(e),this._unmarshal))}_register(e,t,r=this._map,s){if(this._registeredMap.has(e)||this._registeredMap.hasHandle(t))return;let i=this._wrap(e);const[o]=this._wrapHandle(t),u=e instanceof Promise;if(!o||!i&&!u)return;u&&(i=e);const a=this._unwrap(e),[f,d]=this._unwrapHandle(t);if(r.set(i,o,a,f))s&&this._sync.add(a);else throw d&&f.dispose(),new Error("already registered");return[i,o]}_wrap(e){var t,r,s;return Me(this.context,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode,(t=this._options)==null?void 0:t.isWrappable,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0)}_unwrap(e){return R(e,this._symbol)}_wrapHandle(e){var t,r,s;return Ce(this.context,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode,(t=this._options)==null?void 0:t.isHandleWrappable,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0)}_unwrapHandle(e){return A(this.context,e,this._symbolHandle)}}class Be extends Z{constructor(t,r){super(t,r);p(this,"asyncContext");this.asyncContext=t}evalCodeAsync(t,r){return te(this,null,function*(){const s=yield this.asyncContext.evalCodeAsync(t,r);return this._unwrapResultAndUnmarshal(s)})}}m.Arena=Z,m.AsyncArena=Be,m.VMMap=U,m.call=y,m.complexity=le,m.consumeAll=z,m.defaultRegisteredObjects=M,m.isES2015Class=$,m.isHandleObject=J,m.isObject=E,m.json=W,m.marshal=D,m.unmarshal=q,m.walkObject=N,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
80
+ }`,void 0,e,r,c),!0])}function E(n,e){var t;return H(n)&&(t=n[e])!=null?t:n}function F(n,e,t){return Z(n,e,t)?[n.getProp(e,t),!0]:[e,!1]}function Ae(n,e){return H(n)&&!!n[e]}function Z(n,e,t){return!!n.dump(h(n,'(a, s) => (a instanceof Promise) || (a instanceof Date) || (a instanceof ArrayBuffer) || (ArrayBuffer.isView(a)) || (a instanceof Map) || (a instanceof Set) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,t))}class x{constructor(e,t){p(this,"context");p(this,"_map");p(this,"_registeredMap");p(this,"_registeredMapDispose",new Set);p(this,"_transientHandles",new Set);p(this,"_sync",new Set);p(this,"_temporalSync",new Set);p(this,"_symbol",Symbol());p(this,"_symbolHandle");p(this,"_options");p(this,"_isMarshalable",e=>{var r,s;const t=(r=this._options)==null?void 0:r.isMarshalable;return(s=typeof t=="function"?t(this._unwrap(e)):t)!=null?s:"json"});p(this,"_marshalByReference",e=>{var t,r;return!!((r=(t=this._options)==null?void 0:t.marshalByReference)!=null&&r.call(t,this._unwrap(e)))});p(this,"_registerHostRef",(e,t)=>{const r=this._unwrap(e),s=this._map.get(r);return s||(this._map.set(r,t),t)});p(this,"_marshalFind",e=>{var s,i,o;const t=this._unwrap(e);return(o=(i=(s=this._registeredMap.get(e))!=null?s:t!==e?this._registeredMap.get(t):void 0)!=null?i:this._map.get(e))!=null?o:t!==e?this._map.get(t):void 0});p(this,"_marshalPre",(e,t,r)=>{if(r==="json"){this._registerTransient(N(t));return}const s=this._register(e,N(t),this._map);if(s)return s[1];this._registeredMap.has(e)||this._registerTransient(N(t))});p(this,"_registerTransient",e=>{this._transientHandles.add(e)});p(this,"_disposeTransient",e=>{this._transientHandles.delete(e)&&e.alive&&e.dispose()});p(this,"_marshalPreApply",(e,t,r)=>{const s=H(t)?this._unwrap(t):void 0;s&&this._temporalSync.add(s);try{return e.apply(t,r)}finally{s&&this._temporalSync.delete(s)}});p(this,"_marshal",e=>{var o,f,a,u;const t=this._registeredMap.get(e);if(t)return[t,!1];const r=this._marshalByReference(e)?this._unwrap(e):(o=this._wrap(e))!=null?o:e,s=U(r,{ctx:this.context,unmarshal:this._unmarshal,isMarshalable:this._isMarshalable,marshalByReference:this._marshalByReference,registerHostRef:this._registerHostRef,find:this._marshalFind,pre:this._marshalPre,registerTransient:this._registerTransient,disposeTransient:this._disposeTransient,preApply:this._marshalPreApply,custom:(f=this._options)==null?void 0:f.customMarshaller});this._transientHandles.delete(s);const i=(u=(a=this._options)==null?void 0:a.syncEnabled)!=null?u:!0;return[s,!i||!this._map.hasHandle(s)]});p(this,"_preUnmarshal",(e,t)=>{var r,s,i;return(i=this._register(e,t,void 0,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0))==null?void 0:i[0]});p(this,"_unmarshalFind",e=>{var t;return(t=this._registeredMap.getByHandle(e))!=null?t:this._map.getByHandle(e)});p(this,"_unmarshal",e=>{var s,i,o;const t=this._registeredMap.getByHandle(e);if(typeof t!="undefined")return t;if((s=this._options)!=null&&s.marshalByReference){const f=q(this.context,e);if(f)return f.value}const[r]=this._wrapHandle(e);return X(r!=null?r:e,{ctx:this.context,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal,custom:(i=this._options)==null?void 0:i.customUnmarshaller,hostRef:!!((o=this._options)!=null&&o.marshalByReference)})});p(this,"_syncMode",e=>{const t=this._unwrap(e);return this._sync.has(t)||this._temporalSync.has(t)?"both":void 0});p(this,"_unwrapIfNotSynced",e=>{const t=this._unwrap(e);return t instanceof Promise||!this._sync.has(t)?t:e});var r;t!=null&&t.compat&&!("runtime"in e)&&(e.runtime={hasPendingJob:()=>e.hasPendingJob(),executePendingJobs:s=>e.executePendingJobs(s)}),this.context=t!=null&&t.experimentalContextEx?b(e):e,C(this.context),this._options=t,this._symbolHandle=e.unwrapResult(e.evalCode("Symbol()")),this._map=new V(e),this._registeredMap=new V(e),this.registerAll((r=t==null?void 0:t.registeredObjects)!=null?r:A)}dispose(){var e,t;for(const r of this._transientHandles)r.alive&&r.dispose();this._transientHandles.clear(),this._map.dispose(),this._registeredMap.dispose(),this._symbolHandle.dispose(),O(this.context),(t=(e=this.context).disposeEx)==null||t.call(e)}[Symbol.dispose](){this.dispose()}evalCode(e){const t=this.context.evalCode(e);return this._unwrapResultAndUnmarshal(t)}evalModule(e,t="module.js"){const r=this.context.evalCode(e,t,{type:"module"});return this._unwrapResultAndUnmarshal(r)}executePendingJobs(e){const t=this.context.runtime.executePendingJobs(e);if("value"in t)return t.value;throw this._unwrapIfNotSynced(P(t.error,this._unmarshal))}setMemoryLimit(e){this.context.runtime.setMemoryLimit(e)}setMaxStackSize(e){this.context.runtime.setMaxStackSize(e)}getMemoryUsage(){const e=this.context.runtime.computeMemoryUsage();try{return this.context.dump(e)}finally{e.dispose()}}dumpMemoryUsage(){return this.context.runtime.dumpMemoryUsage()}expose(e){for(const[t,r]of Object.entries(e))se(this._marshal(r),s=>{this.context.setProp(this.context.global,t,s)})}sync(e){const t=this._wrap(e);return typeof t=="undefined"?e:(D(t,r=>{const s=this._unwrap(r);this._sync.add(s)}),t)}register(e,t){if(this._registeredMap.has(e))return;const r=typeof t=="string"?this._unwrapResult(this.context.evalCode(t)):t;this.context.sameValue(r,this.context.undefined)||(typeof t=="string"&&this._registeredMapDispose.add(e),this._registeredMap.set(e,r))}registerAll(e){for(const[t,r]of e)this.register(t,r)}unregister(e,t){this._registeredMap.delete(e,this._registeredMapDispose.has(e)||t),this._registeredMapDispose.delete(e)}unregisterAll(e,t){for(const r of e)this.unregister(r,t)}startSync(e){if(!H(e))return;const t=this._unwrap(e);this._sync.add(t)}endSync(e){this._sync.delete(this._unwrap(e))}_unwrapResult(e){if("value"in e)return e.value;throw this._unwrapIfNotSynced(P(e.error,this._unmarshal))}_unwrapResultAndUnmarshal(e){if(e)return this._unwrapIfNotSynced(P(this._unwrapResult(e),this._unmarshal))}_register(e,t,r=this._map,s){if(this._registeredMap.has(e)||this._registeredMap.hasHandle(t))return;let i=this._wrap(e);const[o]=this._wrapHandle(t),f=e instanceof Promise;if(!o||!i&&!f)return;f&&(i=e);const a=this._unwrap(e),[u,l]=this._unwrapHandle(t);if(r.set(i,o,a,u))s&&this._sync.add(a);else throw l&&u.dispose(),new Error("already registered");return[i,o]}_wrap(e){var t,r,s;return Me(this.context,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode,(t=this._options)==null?void 0:t.isWrappable,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0)}_unwrap(e){return E(e,this._symbol)}_wrapHandle(e){var t,r,s;return Ce(this.context,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode,(t=this._options)==null?void 0:t.isHandleWrappable,(s=(r=this._options)==null?void 0:r.syncEnabled)!=null?s:!0)}_unwrapHandle(e){return F(this.context,e,this._symbolHandle)}}class Be extends x{constructor(t,r){super(t,r);p(this,"asyncContext");this.asyncContext=t}evalCodeAsync(t,r){return ne(this,null,function*(){const s=yield this.asyncContext.evalCodeAsync(t,r);return this._unwrapResultAndUnmarshal(s)})}}_.Arena=x,_.AsyncArena=Be,_.VMMap=V,_.call=h,_.complexity=le,_.consumeAll=$,_.defaultRegisteredObjects=A,_.isES2015Class=L,_.isHandleObject=W,_.isObject=H,_.json=z,_.marshal=U,_.unmarshal=X,_.walkObject=D,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quickjs-emscripten-sync",
3
3
  "author": "rot1024",
4
- "version": "1.9.0",
4
+ "version": "1.9.1",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -42,6 +42,7 @@
42
42
  "quickjs-emscripten": "*"
43
43
  },
44
44
  "devDependencies": {
45
+ "@jitl/quickjs-wasmfile-debug-sync": "^0.32.0",
45
46
  "@vitest/coverage-v8": "^4.1.6",
46
47
  "eslint": "^9.39.4",
47
48
  "eslint-config-reearth": "^0.3.8",
package/src/index.ts CHANGED
@@ -79,6 +79,14 @@ export class Arena {
79
79
  _map: VMMap;
80
80
  _registeredMap: VMMap;
81
81
  _registeredMapDispose = new Set<any>();
82
+ // Handles with no owner: "json" copies and BigInt values. Unlike
83
+ // proxy-marshalled objects they are not identity-tracked in `_map`. A nested
84
+ // one is disposed by its parent consumer via `_disposeTransient` as soon as
85
+ // the value has been copied; this set is the fallback that frees any that
86
+ // were never nested (e.g. a top-level value before its caller consumes it) on
87
+ // dispose. Top-level handles are removed in `_marshal` since their caller
88
+ // disposes them via `mayConsume`.
89
+ _transientHandles = new Set<QuickJSHandle>();
82
90
  _sync = new Set<any>();
83
91
  _temporalSync = new Set<any>();
84
92
  _symbol = Symbol();
@@ -108,6 +116,10 @@ export class Arena {
108
116
  * Dispose of the arena and managed handles. This method won't dispose the VM itself, so the VM has to be disposed of manually.
109
117
  */
110
118
  dispose() {
119
+ for (const h of this._transientHandles) {
120
+ if (h.alive) h.dispose();
121
+ }
122
+ this._transientHandles.clear();
111
123
  this._map.dispose();
112
124
  this._registeredMap.dispose();
113
125
  this._symbolHandle.dispose();
@@ -419,8 +431,29 @@ export class Arena {
419
431
  h: QuickJSHandle | QuickJSDeferredPromise,
420
432
  mode: true | "json" | undefined,
421
433
  ): Wrapped<QuickJSHandle> | undefined => {
422
- if (mode === "json") return;
423
- return this._register(t, handleFrom(h), this._map)?.[1];
434
+ if (mode === "json") {
435
+ // json handles have no identity to track; register as transient so they
436
+ // are disposed once consumed (or on dispose) instead of leaking.
437
+ this._registerTransient(handleFrom(h));
438
+ return;
439
+ }
440
+ const registered = this._register(t, handleFrom(h), this._map);
441
+ if (registered) return registered[1];
442
+ // `_register` bails for value-only built-ins that `_wrap` excludes (Map,
443
+ // Set, Date, ArrayBuffer, TypedArray): they are marshalled by value with no
444
+ // entry in `_map`, so their handle has no owner. Track it as transient so a
445
+ // nested one is disposed once consumed, like the json path. (Objects already
446
+ // owned by `_registeredMap` are reached via `_marshalFind`, not here.)
447
+ if (!this._registeredMap.has(t)) this._registerTransient(handleFrom(h));
448
+ return;
449
+ };
450
+
451
+ _registerTransient = (handle: QuickJSHandle): void => {
452
+ this._transientHandles.add(handle);
453
+ };
454
+
455
+ _disposeTransient = (handle: QuickJSHandle): void => {
456
+ if (this._transientHandles.delete(handle) && handle.alive) handle.dispose();
424
457
  };
425
458
 
426
459
  _marshalPreApply = (target: (...args: any[]) => any, that: unknown, args: unknown[]): void => {
@@ -454,10 +487,16 @@ export class Arena {
454
487
  registerHostRef: this._registerHostRef,
455
488
  find: this._marshalFind,
456
489
  pre: this._marshalPre,
490
+ registerTransient: this._registerTransient,
491
+ disposeTransient: this._disposeTransient,
457
492
  preApply: this._marshalPreApply,
458
493
  custom: this._options?.customMarshaller,
459
494
  });
460
495
 
496
+ // A top-level transient handle is disposed by the caller via `mayConsume`,
497
+ // so it must not also be retained (and re-disposed) by the transient set.
498
+ this._transientHandles.delete(handle);
499
+
461
500
  const syncEnabled = this._options?.syncEnabled ?? true;
462
501
  return [handle, !syncEnabled || !this._map.hasHandle(handle)];
463
502
  };
@@ -0,0 +1,178 @@
1
+ import variant from "@jitl/quickjs-wasmfile-debug-sync";
2
+ import { newQuickJSWASMModuleFromVariant } from "quickjs-emscripten";
3
+ import { describe, expect, it } from "vitest";
4
+
5
+ import { Arena } from ".";
6
+
7
+ // A non-plain object that defaultIsMarshalable would reject, forcing the
8
+ // "json" marshal path.
9
+ class Weird {
10
+ x = 1;
11
+ }
12
+
13
+ const jsonIsMarshalable = (t: unknown) =>
14
+ typeof t !== "object" || t === null || Object.getPrototypeOf(t) === Object.prototype
15
+ ? true
16
+ : "json";
17
+
18
+ async function withArena(
19
+ options: ConstructorParameters<typeof Arena>[1],
20
+ fn: (arena: Arena) => void,
21
+ ) {
22
+ const mod = await newQuickJSWASMModuleFromVariant(variant as any);
23
+ const ctx = mod.newContext();
24
+ const arena = new Arena(ctx, options);
25
+ fn(arena);
26
+ arena.dispose();
27
+ // The debug-sync runtime aborts on dispose if any GC object handle leaked, so
28
+ // simply reaching here without an Emscripten abort means no leak.
29
+ expect(() => ctx.dispose()).not.toThrow();
30
+ }
31
+
32
+ describe("json marshal path handle leak", () => {
33
+ it("does not leak when a nested value is marshalled via json", async () => {
34
+ await withArena({ isMarshalable: jsonIsMarshalable }, arena => {
35
+ // Outer object goes through the proxy/object path; the nested `weird`
36
+ // property resolves to "json", creating a JSON.parse handle that nobody
37
+ // would otherwise dispose.
38
+ arena.expose({ obj: { weird: new Weird() } });
39
+ expect(arena.evalCode(`obj.weird.x`)).toBe(1);
40
+ });
41
+ });
42
+
43
+ it("does not leak nor double-dispose a top-level json value", async () => {
44
+ await withArena({ isMarshalable: jsonIsMarshalable }, arena => {
45
+ // host fn receives a top-level json value as an argument; the handle is
46
+ // disposed by mayConsume and must not be re-disposed on dispose().
47
+ let received: any;
48
+ arena.expose({ sink: (v: any) => (received = v) });
49
+ arena.evalCode(`sink`);
50
+ const fn = arena.evalCode(`sink`);
51
+ fn(new Weird());
52
+ expect(received).toEqual({ x: 1 });
53
+ });
54
+ });
55
+
56
+ it("does not leak with the default marshal mode (json)", async () => {
57
+ // With no isMarshalable option the default mode is "json", so even a plain
58
+ // nested object exercises the json path that used to leak. (Functions are
59
+ // dropped by json serialization, so this path only carries plain values.)
60
+ await withArena(undefined, arena => {
61
+ arena.expose({ data: { a: { b: 1 } } });
62
+ expect(arena.evalCode(`data.a.b`)).toBe(1);
63
+ });
64
+ });
65
+
66
+ it("does not leak when a json value round-trips VM -> host", async () => {
67
+ await withArena({ isMarshalable: jsonIsMarshalable }, arena => {
68
+ const received: any[] = [];
69
+ arena.expose({ host: { f: (v: any) => received.push(v) } });
70
+ // VM builds a non-plain object and passes it to the host callback.
71
+ arena.evalCode(`
72
+ const o = Object.create({ tag: "proto" });
73
+ o.a = 1;
74
+ host.f({ nested: o });
75
+ `);
76
+ expect(received).toEqual([{ nested: { a: 1 } }]);
77
+ });
78
+ });
79
+ });
80
+
81
+ describe("value-marshalled built-ins do not leak when nested", () => {
82
+ // Map/Set/Date/ArrayBuffer/TypedArray are excluded from proxy wrapping and
83
+ // marshalled by value, so they get no entry in `_map`. A top-level one is
84
+ // disposed by mayConsume, but a nested one used to have no owner and leaked
85
+ // its handle (aborting the debug runtime on dispose).
86
+ const builtinMarshalable = (t: unknown) =>
87
+ t instanceof Map || t instanceof Set ? true : jsonIsMarshalable(t);
88
+
89
+ it("nested Map", async () => {
90
+ await withArena({ isMarshalable: builtinMarshalable }, arena => {
91
+ arena.expose({ data: { m: new Map<string, unknown>([["b", new Weird()]]) } });
92
+ expect(arena.evalCode(`data.m.get("b").x`)).toBe(1);
93
+ });
94
+ });
95
+
96
+ it("nested Set", async () => {
97
+ await withArena({ isMarshalable: builtinMarshalable }, arena => {
98
+ arena.expose({ data: { s: new Set<number>([1, 2]) } });
99
+ expect(arena.evalCode(`data.s.size`)).toBe(2);
100
+ });
101
+ });
102
+
103
+ it("nested Date and TypedArray", async () => {
104
+ await withArena({ isMarshalable: true }, arena => {
105
+ arena.expose({ data: { d: new Date(0), a: new Uint8Array([1, 2, 3]) } });
106
+ expect(arena.evalCode(`data.a[1]`)).toBe(2);
107
+ });
108
+ });
109
+
110
+ it("deeply nested Map", async () => {
111
+ await withArena({ isMarshalable: builtinMarshalable }, arena => {
112
+ arena.expose({ data: { a: { b: { m: new Map<string, number>([["x", 9]]) } } } });
113
+ expect(arena.evalCode(`data.a.b.m.get("x")`)).toBe(9);
114
+ });
115
+ });
116
+ });
117
+
118
+ describe("transient handles are freed as they are consumed (no accumulation)", () => {
119
+ // Marshal `make(i)` many times, disposing the top-level handle each time
120
+ // (mirroring `mayConsume`). With syncEnabled:false nothing is retained in
121
+ // `_map`, so any growth in live VM memory / object count is a genuine leak of
122
+ // a nested transient (json copy or BigInt) that was not disposed.
123
+ async function liveGrowth(
124
+ make: (i: number) => unknown,
125
+ isMarshalable: ConstructorParameters<typeof Arena>[1] extends infer O
126
+ ? O extends { isMarshalable?: infer M }
127
+ ? M
128
+ : never
129
+ : never,
130
+ ) {
131
+ const mod = await newQuickJSWASMModuleFromVariant(variant as any);
132
+ const ctx = mod.newContext();
133
+ const arena = new Arena(ctx, { isMarshalable, syncEnabled: false }) as any;
134
+ const mem = () => ctx.runtime.computeMemoryUsage().consume((h: any) => ctx.dump(h));
135
+ const marshalOne = (i: number) => {
136
+ // `_marshal` returns [handle, shouldBeDisposed]; honour it like mayConsume.
137
+ const [h, shouldDispose] = arena._marshal(make(i));
138
+ if (shouldDispose && h.alive) h.dispose();
139
+ };
140
+ // Warm up so one-time shape/atom allocations are not counted.
141
+ for (let i = 0; i < 30; i++) marshalOne(i);
142
+ const before = mem();
143
+ for (let i = 0; i < 200; i++) marshalOne(i + 100000);
144
+ const after = mem();
145
+ arena.dispose();
146
+ ctx.dispose();
147
+ return {
148
+ usedBytes: after.memory_used_size - before.memory_used_size,
149
+ objects: after.obj_count - before.obj_count,
150
+ };
151
+ }
152
+
153
+ it("does not leak nested BigInt values", async () => {
154
+ // Pre-fix this leaked ~7 bytes of BigInt storage per iteration.
155
+ const { usedBytes } = await liveGrowth(i => ({ b: BigInt(i) * 99999999n }), true);
156
+ expect(usedBytes).toBeLessThan(400);
157
+ });
158
+
159
+ it("does not accumulate nested json objects", async () => {
160
+ // Pre-fix each iteration retained one JSON.parse object until dispose.
161
+ const { objects } = await liveGrowth(() => ({ w: new Weird() }), jsonIsMarshalable);
162
+ expect(objects).toBeLessThan(20);
163
+ });
164
+
165
+ it("frees json/BigInt values stored in a Map or Set", async () => {
166
+ // A top-level Map/Set so the collection handle itself is not retained; this
167
+ // isolates the lifetime of its BigInt/json entries, which must be freed.
168
+ const collMarshalable = (t: unknown) =>
169
+ t instanceof Map || t instanceof Set ? true : jsonIsMarshalable(t);
170
+ const map = await liveGrowth(
171
+ i => new Map<string, unknown>([["a", BigInt(i)], ["b", new Weird()]]),
172
+ collMarshalable,
173
+ );
174
+ expect(map.usedBytes).toBeLessThan(400);
175
+ const set = await liveGrowth(() => new Set<unknown>([new Weird()]), collMarshalable);
176
+ expect(set.usedBytes).toBeLessThan(400);
177
+ });
178
+ });
@@ -12,6 +12,7 @@ export default function marshalFunction(
12
12
  unmarshal: (handle: QuickJSHandle) => unknown,
13
13
  preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
14
14
  preApply?: (target: (...args: any[]) => any, thisArg: unknown, args: unknown[]) => any,
15
+ disposeTransient: (handle: QuickJSHandle) => void = () => {},
15
16
  ): QuickJSHandle | undefined {
16
17
  if (typeof target !== "function") return;
17
18
 
@@ -24,7 +25,10 @@ export default function marshalFunction(
24
25
  // Class constructors cannot be invoked without new expression, and new.target is not changed
25
26
  const result = new target(...args);
26
27
  Object.entries(result).forEach(([key, value]) => {
27
- ctx.setProp(this, key, marshal(value));
28
+ const valueHandle = marshal(value);
29
+ ctx.setProp(this, key, valueHandle);
30
+ // setProp dup'd the value into `this`; drop ours if it was transient.
31
+ disposeTransient(valueHandle);
28
32
  });
29
33
  return this;
30
34
  }
@@ -47,7 +51,7 @@ export default function marshalFunction(
47
51
  );
48
52
 
49
53
  const handle = preMarshal(target, raw) ?? raw;
50
- marshalProperties(ctx, target, raw, marshal);
54
+ marshalProperties(ctx, target, raw, marshal, disposeTransient);
51
55
 
52
56
  return handle;
53
57
  }
@@ -16,6 +16,12 @@ export type Options = {
16
16
  marshalByReference?: (target: unknown) => boolean;
17
17
  registerHostRef?: (target: unknown, handle: QuickJSHandle) => QuickJSHandle;
18
18
  find: (target: unknown) => QuickJSHandle | undefined;
19
+ // Track a handle that nobody else owns (json copies, BigInt) so it can be
20
+ // disposed once consumed.
21
+ registerTransient?: (handle: QuickJSHandle) => void;
22
+ // Dispose a handle previously registered as transient, right after a parent
23
+ // consumer has copied it into the parent value. A no-op for owned handles.
24
+ disposeTransient?: (handle: QuickJSHandle) => void;
19
25
  pre: (
20
26
  target: unknown,
21
27
  handle: QuickJSHandle | QuickJSDeferredPromise,
@@ -31,6 +37,10 @@ export function marshal(target: unknown, options: Options): QuickJSHandle {
31
37
  {
32
38
  const primitive = marshalPrimitive(ctx, target);
33
39
  if (primitive) {
40
+ // BigInt handles are heap-allocated and, unlike strings and numbers, are
41
+ // not reclaimed unless explicitly disposed. Track them as transient so a
42
+ // nested one is freed by its parent consumer (or on dispose as a fallback).
43
+ if (typeof target === "bigint") options.registerTransient?.(primitive);
34
44
  return primitive;
35
45
  }
36
46
  }
@@ -59,12 +69,13 @@ export function marshal(target: unknown, options: Options): QuickJSHandle {
59
69
  }
60
70
 
61
71
  const marshal2 = (t: unknown) => marshal(t, options);
72
+ const disposeTransient = options.disposeTransient;
62
73
  return (
63
74
  marshalCustom(ctx, target, pre2, [...defaultCustom, ...(options.custom ?? [])]) ??
64
75
  marshalPromise(ctx, target, marshal2, pre2) ??
65
- marshalFunction(ctx, target, marshal2, unmarshal, pre2, options.preApply) ??
66
- marshalMapSet(ctx, target, marshal2, pre2) ??
67
- marshalObject(ctx, target, marshal2, pre2) ??
76
+ marshalFunction(ctx, target, marshal2, unmarshal, pre2, options.preApply, disposeTransient) ??
77
+ marshalMapSet(ctx, target, marshal2, pre2, disposeTransient) ??
78
+ marshalObject(ctx, target, marshal2, pre2, disposeTransient) ??
68
79
  ctx.undefined
69
80
  );
70
81
  }
@@ -7,12 +7,18 @@ export default function marshalMapSet(
7
7
  target: unknown,
8
8
  marshal: (target: unknown) => QuickJSHandle,
9
9
  preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
10
+ disposeTransient: (handle: QuickJSHandle) => void = () => {},
10
11
  ): QuickJSHandle | undefined {
11
12
  if (target instanceof Map) {
12
13
  const raw = call(ctx, "() => new Map()");
13
14
  const handle = preMarshal(target, raw) ?? raw;
14
15
  for (const [k, v] of target) {
15
- call(ctx, "(m, k, v) => m.set(k, v)", undefined, raw, marshal(k), marshal(v)).dispose();
16
+ const kh = marshal(k);
17
+ const vh = marshal(v);
18
+ call(ctx, "(m, k, v) => m.set(k, v)", undefined, raw, kh, vh).dispose();
19
+ // set() has taken its own references; drop ours if they were transient.
20
+ disposeTransient(kh);
21
+ disposeTransient(vh);
16
22
  }
17
23
  return handle;
18
24
  }
@@ -21,7 +27,10 @@ export default function marshalMapSet(
21
27
  const raw = call(ctx, "() => new Set()");
22
28
  const handle = preMarshal(target, raw) ?? raw;
23
29
  for (const v of target) {
24
- call(ctx, "(s, v) => s.add(v)", undefined, raw, marshal(v)).dispose();
30
+ const vh = marshal(v);
31
+ call(ctx, "(s, v) => s.add(v)", undefined, raw, vh).dispose();
32
+ // add() has taken its own reference; drop ours if it was transient.
33
+ disposeTransient(vh);
25
34
  }
26
35
  return handle;
27
36
  }
@@ -9,6 +9,7 @@ export default function marshalObject(
9
9
  target: unknown,
10
10
  marshal: (target: unknown) => QuickJSHandle,
11
11
  preMarshal: (target: unknown, handle: QuickJSHandle) => QuickJSHandle | undefined,
12
+ disposeTransient: (handle: QuickJSHandle) => void = () => {},
12
13
  ): QuickJSHandle | undefined {
13
14
  if (typeof target !== "object" || target === null) return;
14
15
 
@@ -23,9 +24,11 @@ export default function marshalObject(
23
24
  : undefined;
24
25
  if (prototypeHandle) {
25
26
  call(ctx, "Object.setPrototypeOf", undefined, handle, prototypeHandle).dispose();
27
+ // setPrototypeOf has taken its own reference; drop ours if it was transient.
28
+ disposeTransient(prototypeHandle);
26
29
  }
27
30
 
28
- marshalProperties(ctx, target, raw, marshal);
31
+ marshalProperties(ctx, target, raw, marshal, disposeTransient);
29
32
 
30
33
  return handle;
31
34
  }
@@ -7,13 +7,21 @@ export default function marshalProperties(
7
7
  target: object | ((...args: any[]) => any),
8
8
  handle: QuickJSHandle,
9
9
  marshal: (target: unknown) => QuickJSHandle,
10
+ disposeTransient: (handle: QuickJSHandle) => void = () => {},
10
11
  ): void {
11
12
  const descs = ctx.newObject();
13
+ // Property values may be transient (json copies / BigInt) with no owner; once
14
+ // `Object.defineProperties` has copied them into `handle` the standalone
15
+ // handles are redundant and disposed below. Owned handles are left untouched.
16
+ const transient: QuickJSHandle[] = [];
12
17
  const cb = (key: string | number | symbol, desc: PropertyDescriptor) => {
13
18
  const keyHandle = marshal(key);
14
19
  const valueHandle = typeof desc.value === "undefined" ? undefined : marshal(desc.value);
15
20
  const getHandle = typeof desc.get === "undefined" ? undefined : marshal(desc.get);
16
21
  const setHandle = typeof desc.set === "undefined" ? undefined : marshal(desc.set);
22
+ if (valueHandle) transient.push(valueHandle);
23
+ if (getHandle) transient.push(getHandle);
24
+ if (setHandle) transient.push(setHandle);
17
25
 
18
26
  ctx.newObject().consume(descObj => {
19
27
  Object.entries(desc).forEach(([k, v]) => {
@@ -41,6 +49,9 @@ export default function marshalProperties(
41
49
  Object.getOwnPropertySymbols(desc).forEach(k => cb(k, (desc as any)[k]));
42
50
 
43
51
  call(ctx, `Object.defineProperties`, undefined, handle, descs).dispose();
52
+ // Safe only after defineProperties has dup'd the values into `handle`; `descs`
53
+ // still holds its own references until its own dispose() in the finally.
54
+ for (const h of transient) disposeTransient(h);
44
55
  } finally {
45
56
  descs.dispose();
46
57
  }
package/src/vmutil.ts CHANGED
@@ -119,7 +119,9 @@ export function isHandleObject(ctx: QuickJSContext, h: QuickJSHandle): boolean {
119
119
  export function json(ctx: QuickJSContext, target: any): QuickJSHandle {
120
120
  const json = JSON.stringify(target);
121
121
  if (!json) return ctx.undefined;
122
- return call(ctx, `JSON.parse`, undefined, ctx.newString(json));
122
+ // `call` does not dispose its arguments, so the intermediate string handle
123
+ // must be consumed here or it leaks on every json marshal.
124
+ return ctx.newString(json).consume(s => call(ctx, `JSON.parse`, undefined, s));
123
125
  }
124
126
 
125
127
  /**