quickjs-emscripten-sync 1.5.2 → 1.7.0
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.
- package/dist/index.d.ts +139 -5
- package/dist/quickjs-emscripten-sync.mjs +420 -329
- package/dist/quickjs-emscripten-sync.umd.js +7 -7
- package/package.json +7 -7
- package/src/index.test.ts +420 -0
- package/src/index.ts +155 -0
- package/src/vmutil.ts +4 -2
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
(function(m,v){typeof exports=="object"&&typeof module!="undefined"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(m=typeof globalThis!="undefined"?globalThis:m||self,v(m.QuickjsEmscriptenSync={}))})(this,function(m){"use strict";var ve=Object.defineProperty;var we=(m,v,j)=>v in m?ve(m,v,{enumerable:!0,configurable:!0,writable:!0,value:j}):m[v]=j;var c=(m,v,j)=>
|
|
1
|
+
(function(m,v){typeof exports=="object"&&typeof module!="undefined"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(m=typeof globalThis!="undefined"?globalThis:m||self,v(m.QuickjsEmscriptenSync={}))})(this,(function(m){"use strict";var ve=Object.defineProperty;var we=(m,v,j)=>v in m?ve(m,v,{enumerable:!0,configurable:!0,writable:!0,value:j}):m[v]=j;var c=(m,v,j)=>we(m,typeof v!="symbol"?v+"":v,j);const v=n=>{const e=new j(n);return new Proxy(n,{get(t,r,s){return r in e?e[r]:Reflect.get(t,r,s)}})};class j{constructor(e){c(this,"context");c(this,"fn");c(this,"fnGenerator");c(this,"fnCounter",Number.MIN_SAFE_INTEGER);c(this,"fnMap",new Map);c(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 o=e.getNumber(r),i=t.get(o);if(!i)throw new Error("function is not registered");return i.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 k=[[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
|
|
8
|
+
})`))}disposeEx(){this.fnGenerator.dispose(),this.fn.dispose()}}const k=[[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 J(n,e){const t=n.unwrapResult(n.evalCode(e)),r=(o,...i)=>n.unwrapResult(n.callFunction(t,o!=null?o:n.undefined,...i)),s=()=>t.dispose();return r.dispose=s,r[Symbol.dispose]=s,r.alive=!0,Object.defineProperty(r,"alive",{get:()=>t.alive}),r}function _(n,e,t,...r){const s=J(n,e);try{return s(t,...r)}finally{s.dispose()}}function C(n,e,t){return n.dump(_(n,"Object.is",void 0,e,t))}function W(n,e,t){return n.dump(_(n,"(a, b) => a instanceof b",void 0,e,t))}function F(n,e){return n.dump(_(n,'a => typeof a === "object" && a !== null || typeof a === "function"',void 0,e))}function H(n,e){const t=JSON.stringify(e);return t?_(n,"JSON.parse",void 0,n.newString(t)):n.undefined}function z(n,e){try{return e(n)}finally{for(const t of n)t.alive&&t.dispose()}}function $([n,e],t){try{return t(n)}finally{e&&n.dispose()}}function S(n,e){try{return e(...n.map(t=>t[0]))}finally{for(const[t,r]of n)r&&t.dispose()}}function q(n){return"handle"in n}function L(n){return q(n)?n.handle:n}function Q(n,e,t,r){var o;let s;for(const i of r)if(s=i(e,n),s)break;return s?(o=t(e,s))!=null?o:s:void 0}function V(n,e){return typeof n!="symbol"?void 0:_(e,"d => Symbol(d)",void 0,n.description?e.newString(n.description):e.undefined)}function X(n,e){return n instanceof Date?_(e,"d => new Date(d)",void 0,e.newNumber(n.getTime())):void 0}const Y=[V,X];function N(n){return typeof n=="function"&&/^class\s/.test(Function.prototype.toString.call(n))}function g(n){return typeof n=="function"||typeof n=="object"&&n!==null}function O(n,e){const t=new Set,r=s=>{if(!(!g(s)||t.has(s)||(e==null?void 0:e(s,t))===!1)){if(t.add(s),Array.isArray(s)){for(const o of s)r(o);return}if(typeof s=="object"){const o=Object.getPrototypeOf(s);o&&o!==Object.prototype&&r(o)}for(const o of Object.values(Object.getOwnPropertyDescriptors(s)))"value"in o&&r(o.value),"get"in o&&r(o.get),"set"in o&&r(o.set)}};return r(n),t}function Z(n,e){return O(n,e?(t,r)=>r.size<e:void 0).size}function K(){let n=()=>{},e=()=>{};return{promise:new Promise((r,s)=>{n=r,e=s}),resolve:n,reject:e}}function A(n,e,t,r){const s=n.newObject(),o=(a,u)=>{const p=r(a),l=typeof u.value=="undefined"?void 0:r(u.value),f=typeof u.get=="undefined"?void 0:r(u.get),d=typeof u.set=="undefined"?void 0:r(u.set);n.newObject().consume(h=>{Object.entries(u).forEach(([y,b])=>{const w=y==="value"?l:y==="get"?f:y==="set"?d:b?n.true:n.false;w&&n.setProp(h,y,w)}),n.setProp(s,p,h)})},i=Object.getOwnPropertyDescriptors(e);Object.entries(i).forEach(([a,u])=>o(a,u)),Object.getOwnPropertySymbols(i).forEach(a=>o(a,i[a])),_(n,"Object.defineProperties",void 0,t,s).dispose(),s.dispose()}function x(n,e,t,r,s,o){var u;if(typeof e!="function")return;const i=n.newFunction(e.name,function(...p){const l=r(this),f=p.map(d=>r(d));if(N(e)&&g(l)){const d=new e(...f);return Object.entries(d).forEach(([h,y])=>{n.setProp(this,h,t(y))}),this}return t(o?o(e,l,f):e.apply(l,f))}).consume(p=>_(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,p)),a=(u=
|
|
13
|
+
}`,void 0,p)),a=(u=s(e,i))!=null?u:i;return A(n,e,i,t),a}function ee(n,e,t){var o;const r=H(n,e);return(o=t(e,r))!=null?o:r}function te(n,e,t,r){var u;if(typeof e!="object"||e===null)return;const s=Array.isArray(e)?n.newArray():n.newObject(),o=(u=r(e,s))!=null?u:s,i=Object.getPrototypeOf(e),a=i&&i!==Object.prototype&&i!==Array.prototype?t(i):void 0;return a&&_(n,"Object.setPrototypeOf",void 0,o,a).dispose(),A(n,e,s,t),o}function ne(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"object":return e===null?n.null:void 0}}function re(n,e,t,r){var o;if(!(e instanceof Promise))return;const s=n.newPromise();return e.then(i=>s.resolve(t(i)),i=>s.reject(t(i))),(o=r(e,s))!=null?o:s.handle}function E(n,e){var l,f,d,h,y;const{ctx:t,unmarshal:r,isMarshalable:s,find:o,pre:i}=e;{const b=ne(t,n);if(b)return b}{const b=o(n);if(b)return b}const a=s==null?void 0:s(n);if(a===!1)return t.undefined;const u=(b,w)=>i(b,w,a);if(a==="json")return ee(t,n,u);const p=b=>E(b,e);return(y=(h=(d=(f=Q(t,n,u,[...Y,...(l=e.custom)!=null?l:[]]))!=null?f:re(t,n,p,u))!=null?d:x(t,n,p,r,u,e.preApply))!=null?h:te(t,n,p,u))!=null?y:t.undefined}function se(n,e,t,r){var o;let s;for(const i of r)if(s=i(e,n),s)break;return s?(o=t(s,e))!=null?o:s:void 0}function oe(n,e){if(e.typeof(n)!=="symbol")return;const t=e.getString(e.getProp(n,"description"));return Symbol(t)}function ie(n,e){if(!e.dump(_(e,"a => a instanceof Date",void 0,n)))return;const t=e.getNumber(_(e,"a => a.getTime()",void 0,n));return new Date(t)}const ue=[oe,ie];function D(n,e,t,r){n.newFunction("",(s,o)=>{const[i]=r(s);if(typeof i!="string"&&typeof i!="number"&&typeof i!="symbol")return;const a=[["value",!0],["get",!0],["set",!0],["configurable",!1],["enumerable",!1],["writable",!1]].reduce((u,[p,l])=>{const f=n.getProp(o,p),d=n.typeof(f);if(d==="undefined")return u;if(!l&&d==="boolean")return u[p]=n.dump(n.getProp(o,p)),u;const[h,y]=r(f);return y&&f.dispose(),u[p]=h,u},{});Object.defineProperty(t,i,a)}).consume(s=>{_(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,
|
|
17
|
+
}`,void 0,e,s).dispose()})}function ae(n,e,t,r,s){var a;if(n.typeof(e)!=="function")return;const o=function(...u){return S([t(this),...u.map(p=>t(p))],(p,...l)=>{if(new.target){const[y]=r(_(n,"(Cls, ...args) => new Cls(...args)",p,e,...l));return Object.defineProperties(this,Object.getOwnPropertyDescriptors(y)),this}const f=n.unwrapResult(n.callFunction(e,p,...l)),[d,h]=r(f);return h&&f.dispose(),d})},i=(a=s(o,e))!=null?a:o;return D(n,e,o,r),i}function pe(n,e,t,r){var a;if(n.typeof(e)!=="object"||n.unwrapResult(n.evalCode("o => o === null")).consume(u=>n.dump(n.unwrapResult(n.callFunction(u,n.undefined,e)))))return;const s=_(n,"Array.isArray",void 0,e).consume(u=>n.dump(u))?[]:{},o=(a=r(s,e))!=null?a:s,i=_(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).consume(u=>{if(n.typeof(u)==="undefined")return;const[p]=t(u);return p});return typeof i=="object"&&Object.setPrototypeOf(o,i),D(n,e,
|
|
20
|
+
}`,void 0,e).consume(u=>{if(n.typeof(u)==="undefined")return;const[p]=t(u);return p});return typeof i=="object"&&Object.setPrototypeOf(o,i),D(n,e,s,t),o}function fe(n,e){const t=n.typeof(e);return t==="undefined"||t==="number"||t==="string"||t==="boolean"?[n.dump(e),!0]:t==="object"&&n.unwrapResult(n.evalCode("a => a === null")).consume(s=>n.dump(n.unwrapResult(n.callFunction(s,n.undefined,e))))?[null,!0]:[void 0,!1]}function ce(n,e,t,r){var p;if(!le(n,e))return;const s=K(),[o,i]=t(s.resolve),[a,u]=t(s.reject);return _(n,"(p, res, rej) => { p.then(res, rej); }",void 0,e,o,a),i&&o.dispose(),u&&a.dispose(),(p=r(s.promise,e))!=null?p:s.promise}function le(n,e){return e.owner?n.unwrapResult(n.evalCode("Promise")).consume(t=>e.owner?W(n,e,t):!1):!1}function B(n,e){const[t]=T(n,e);return t}function T(n,e){var u,p,l,f;const{ctx:t,marshal:r,find:s,pre:o}=e;{const[d,h]=fe(t,n);if(h)return[d,!1]}{const d=s(n);if(d)return[d,!0]}const i=d=>T(d,e);return[(f=(l=(p=se(t,n,o,[...ue,...(u=e.custom)!=null?u:[]]))!=null?p:ce(t,n,r,o))!=null?l:ae(t,n,r,i,o))!=null?f:pe(t,n,i,o),!1]}class M{constructor(e){c(this,"ctx");c(this,"_map1",new Map);c(this,"_map2",new Map);c(this,"_map3",new Map);c(this,"_map4",new Map);c(this,"_counterMap",new Map);c(this,"_disposables",new Set);c(this,"_mapGet");c(this,"_mapSet");c(this,"_mapDelete");c(this,"_mapClear");c(this,"_counter",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(
|
|
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 a;if(!t.alive||s&&!s.alive)return!1;const o=(a=this.get(e))!=null?a:this.get(r);if(o)return o===t||o===s;const i=this._counter++;return this._map1.set(e,i),this._map3.set(i,t),this._counterMap.set(i,e),r&&(this._map2.set(r,i),s&&this._map4.set(i,s)),this.ctx.newNumber(i).consume(u=>{this._call(this._mapSet,void 0,t,u,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._map1.get(e))!=null?s:this._map2.get(e),r=typeof t=="number"?this._map3.get(t):void 0;if(r){if(!r.alive){this.delete(e);return}return r}}getByHandle(e){if(e.alive)return this._counterMap.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._map1.keys()}delete(e,t){var i;const r=(i=this._map1.get(e))!=null?i:this._map2.get(e);if(typeof r=="undefined")return;const s=this._map3.get(r),o=this._map4.get(r);this._call(this._mapDelete,void 0,...[s,o].filter(a=>!!(a!=null&&a.alive))),this._map1.delete(e),this._map2.delete(e),this._map3.delete(r),this._map4.delete(r);for(const[a,u]of this._map1)if(u===r){this._map1.delete(a);break}for(const[a,u]of this._map2)if(u===r){this._map2.delete(a);break}for(const[a,u]of this._counterMap)if(u===e){this._counterMap.delete(a);break}t&&(s!=null&&s.alive&&s.dispose(),o!=null&&o.alive&&o.dispose())}deleteByHandle(e,t){const r=this.getByHandle(e);typeof r!="undefined"&&this.delete(r,t)}clear(){this._counter=0,this._map1.clear(),this._map2.clear(),this._map3.clear(),this._map4.clear(),this._counterMap.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._map3.values())e.alive&&e.dispose();for(const e of this._map4.values())e.alive&&e.dispose();this._disposables.clear(),this.clear()}get size(){return this._map1.size}[Symbol.iterator](){const e=this._map1.keys();return{next:()=>{for(;;){const t=e.next();if(t.done)return{value:void 0,done:!0};const r=this._map1.get(t.value);if(typeof r=="undefined")continue;const s=this._map3.get(r),o=this._map4.get(r);if(!s)continue;const i=this._get2(r);return{value:[t.value,s,i,o],done:!1}}}}}_get2(e){for(const[t,r]of this._map2)if(r===e)return t}_call(e,t,...r){return this.ctx.unwrapResult(this.ctx.callFunction(e,typeof t=="undefined"?this.ctx.undefined:t,...r))}}function de(n,e,t,r,s,o,i){if(!g(e)||e instanceof Promise||e instanceof Date||i&&!i(e))return;if(he(e,t))return e;const a=new Proxy(e,{get(u,p){return p===t?u:Reflect.get(u,p)},set(u,p,l,f){var y;const d=P(l,t),h=(y=o==null?void 0:o(f))!=null?y:"host";return h!=="vm"&&!Reflect.set(u,p,d,f)||h==="host"||!n.alive||S([s(f),s(p),s(d)],(b,w,I)=>{const[G,_e]=R(n,b,r);_e?G.consume(be=>n.setProp(be,w,I)):n.setProp(G,w,I)}),!0},deleteProperty(u,p){var f;const l=(f=o==null?void 0:o(a))!=null?f:"host";return S([s(a),s(p)],(d,h)=>{const[y,b]=R(n,d,r);if(l==="vm"||Reflect.deleteProperty(u,p)){if(l==="host"||!n.alive)return!0;b?y.consume(w=>_(n,"(a, b) => delete a[b]",void 0,w,h)):_(n,"(a, b) => delete a[b]",void 0,y,h)}return!0})}});return a}function me(n,e,t,r,s,o,i){if(!F(n,e)||i&&!i(e,n))return[void 0,!1];if(U(n,e,r))return[e,!1];const a=l=>{const f=o==null?void 0:o(s(l));return typeof f=="string"?n.newString(f):n.undefined},u=(l,f,d)=>{const h=s(l);if(!h)return;const y=s(f);if(y==="__proto__")return;const b=s(d);P(h,t)[y]=b},p=(l,f)=>{const d=s(l);if(!d)return;const h=s(f);delete P(d,t)[h]};return n.newFunction("proxyFuncs",(l,...f)=>{switch(n.getNumber(l)){case 1:return a(f[0]);case 2:return u(f[0],f[1],f[2]);case 3:return p(f[0],f[1])}return n.undefined}).consume(l=>[_(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)
|
|
@@ -68,4 +68,4 @@
|
|
|
68
68
|
},
|
|
69
69
|
});
|
|
70
70
|
return rec;
|
|
71
|
-
}`,void 0,e,
|
|
71
|
+
}`,void 0,e,r,l),!0])}function P(n,e){var t;return g(n)&&(t=n[e])!=null?t:n}function R(n,e,t){return U(n,e,t)?[n.getProp(e,t),!0]:[e,!1]}function he(n,e){return g(n)&&!!n[e]}function U(n,e,t){return!!n.dump(_(n,'(a, s) => (a instanceof Promise) || (a instanceof Date) || (typeof a === "object" && a !== null || typeof a === "function") && !!a[s]',void 0,e,t))}class ye{constructor(e,t){c(this,"context");c(this,"_map");c(this,"_registeredMap");c(this,"_registeredMapDispose",new Set);c(this,"_sync",new Set);c(this,"_temporalSync",new Set);c(this,"_symbol",Symbol());c(this,"_symbolHandle");c(this,"_options");c(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"});c(this,"_marshalFind",e=>{var s,o,i;const t=this._unwrap(e);return(i=(o=(s=this._registeredMap.get(e))!=null?s:t!==e?this._registeredMap.get(t):void 0)!=null?o:this._map.get(e))!=null?i:t!==e?this._map.get(t):void 0});c(this,"_marshalPre",(e,t,r)=>{var s;if(r!=="json")return(s=this._register(e,L(t),this._map))==null?void 0:s[1]});c(this,"_marshalPreApply",(e,t,r)=>{const s=g(t)?this._unwrap(t):void 0;s&&this._temporalSync.add(s);try{return e.apply(t,r)}finally{s&&this._temporalSync.delete(s)}});c(this,"_marshal",e=>{var s,o;const t=this._registeredMap.get(e);if(t)return[t,!1];const r=E((s=this._wrap(e))!=null?s:e,{ctx:this.context,unmarshal:this._unmarshal,isMarshalable:this._isMarshalable,find:this._marshalFind,pre:this._marshalPre,preApply:this._marshalPreApply,custom:(o=this._options)==null?void 0:o.customMarshaller});return[r,!this._map.hasHandle(r)]});c(this,"_preUnmarshal",(e,t)=>{var r;return(r=this._register(e,t,void 0,!0))==null?void 0:r[0]});c(this,"_unmarshalFind",e=>{var t;return(t=this._registeredMap.getByHandle(e))!=null?t:this._map.getByHandle(e)});c(this,"_unmarshal",e=>{var s;const t=this._registeredMap.getByHandle(e);if(typeof t!="undefined")return t;const[r]=this._wrapHandle(e);return B(r!=null?r:e,{ctx:this.context,marshal:this._marshal,find:this._unmarshalFind,pre:this._preUnmarshal,custom:(s=this._options)==null?void 0:s.customUnmarshaller})});c(this,"_syncMode",e=>{const t=this._unwrap(e);return this._sync.has(t)||this._temporalSync.has(t)?"both":void 0});c(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?v(e):e,this._options=t,this._symbolHandle=e.unwrapResult(e.evalCode("Symbol()")),this._map=new M(e),this._registeredMap=new M(e),this.registerAll((r=t==null?void 0:t.registeredObjects)!=null?r:k)}dispose(){var e,t;this._map.dispose(),this._registeredMap.dispose(),this._symbolHandle.dispose(),(t=(e=this.context).disposeEx)==null||t.call(e)}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(t.error.consume(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))$(this._marshal(r),s=>{this.context.setProp(this.context.global,t,s)})}sync(e){const t=this._wrap(e);return typeof t=="undefined"?e:(O(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;C(this.context,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(!g(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(e.error.consume(this._unmarshal))}_unwrapResultAndUnmarshal(e){if(e)return this._unwrapIfNotSynced(this._unwrapResult(e).consume(this._unmarshal))}_register(e,t,r=this._map,s){if(this._registeredMap.has(e)||this._registeredMap.hasHandle(t))return;let o=this._wrap(e);const[i]=this._wrapHandle(t),a=e instanceof Promise;if(!i||!o&&!a)return;a&&(o=e);const u=this._unwrap(e),[p,l]=this._unwrapHandle(t);if(r.set(o,i,u,p))s&&this._sync.add(u);else throw l&&p.dispose(),new Error("already registered");return[o,i]}_wrap(e){var t;return de(this.context,e,this._symbol,this._symbolHandle,this._marshal,this._syncMode,(t=this._options)==null?void 0:t.isWrappable)}_unwrap(e){return P(e,this._symbol)}_wrapHandle(e){var t;return me(this.context,e,this._symbol,this._symbolHandle,this._unmarshal,this._syncMode,(t=this._options)==null?void 0:t.isHandleWrappable)}_unwrapHandle(e){return R(this.context,e,this._symbolHandle)}}m.Arena=ye,m.VMMap=M,m.call=_,m.complexity=Z,m.consumeAll=z,m.defaultRegisteredObjects=k,m.eq=C,m.isES2015Class=N,m.isHandleObject=F,m.isObject=g,m.json=H,m.marshal=E,m.unmarshal=B,m.walkObject=O,Object.defineProperty(m,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.
|
|
4
|
+
"version": "1.7.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./dist/quickjs-emscripten-sync.umd.js",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@vitest/coverage-c8": "^0.28.5",
|
|
35
|
-
"eslint": "^8.
|
|
35
|
+
"eslint": "^8.57.1",
|
|
36
36
|
"eslint-config-reearth": "^0.2.1",
|
|
37
|
-
"prettier": "^2.
|
|
38
|
-
"quickjs-emscripten": "^0.
|
|
39
|
-
"typescript": "^
|
|
40
|
-
"vite": "^
|
|
41
|
-
"vite-plugin-dts": "^
|
|
37
|
+
"prettier": "^2.8.8",
|
|
38
|
+
"quickjs-emscripten": "^0.29.0",
|
|
39
|
+
"typescript": "^5.7.2",
|
|
40
|
+
"vite": "^6.0.3",
|
|
41
|
+
"vite-plugin-dts": "^4.3.0",
|
|
42
42
|
"vitest": "^0.28.5"
|
|
43
43
|
}
|
|
44
44
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -612,3 +612,423 @@ describe("isMarshalable option", () => {
|
|
|
612
612
|
ctx.dispose();
|
|
613
613
|
});
|
|
614
614
|
});
|
|
615
|
+
|
|
616
|
+
describe("evalModule", () => {
|
|
617
|
+
test("module can modify exposed globals", async () => {
|
|
618
|
+
const ctx = (await getQuickJS()).newContext();
|
|
619
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
620
|
+
|
|
621
|
+
const data = arena.sync({ count: 0, message: "" });
|
|
622
|
+
arena.expose({ data });
|
|
623
|
+
|
|
624
|
+
// Module code can have side effects on exposed globals
|
|
625
|
+
arena.evalModule(`
|
|
626
|
+
data.count = 42;
|
|
627
|
+
data.message = "Hello from module";
|
|
628
|
+
`);
|
|
629
|
+
|
|
630
|
+
expect(data.count).toBe(42);
|
|
631
|
+
expect(data.message).toBe("Hello from module");
|
|
632
|
+
|
|
633
|
+
arena.dispose();
|
|
634
|
+
ctx.dispose();
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
test("module with function side effects", async () => {
|
|
638
|
+
const ctx = (await getQuickJS()).newContext();
|
|
639
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
640
|
+
|
|
641
|
+
const results: number[] = [];
|
|
642
|
+
arena.expose({
|
|
643
|
+
results,
|
|
644
|
+
push: (value: number) => results.push(value),
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
arena.evalModule(`
|
|
648
|
+
push(1);
|
|
649
|
+
push(2);
|
|
650
|
+
push(3);
|
|
651
|
+
`);
|
|
652
|
+
|
|
653
|
+
expect(results).toEqual([1, 2, 3]);
|
|
654
|
+
|
|
655
|
+
arena.dispose();
|
|
656
|
+
ctx.dispose();
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
test("module can define and use internal exports", async () => {
|
|
660
|
+
const ctx = (await getQuickJS()).newContext();
|
|
661
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
662
|
+
|
|
663
|
+
const output = arena.sync({ value: 0 });
|
|
664
|
+
arena.expose({ output });
|
|
665
|
+
|
|
666
|
+
// Module can export and use its own exports internally
|
|
667
|
+
arena.evalModule(`
|
|
668
|
+
export function double(x) {
|
|
669
|
+
return x * 2;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
export const value = 21;
|
|
673
|
+
|
|
674
|
+
// Use the exports internally
|
|
675
|
+
output.value = double(value);
|
|
676
|
+
`);
|
|
677
|
+
|
|
678
|
+
expect(output.value).toBe(42);
|
|
679
|
+
|
|
680
|
+
arena.dispose();
|
|
681
|
+
ctx.dispose();
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
test("module with custom filename", async () => {
|
|
685
|
+
const ctx = (await getQuickJS()).newContext();
|
|
686
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
687
|
+
|
|
688
|
+
const state = arena.sync({ executed: false });
|
|
689
|
+
arena.expose({ state });
|
|
690
|
+
|
|
691
|
+
// Test that custom filename doesn't break functionality
|
|
692
|
+
arena.evalModule(`state.executed = true;`, "custom-module.js");
|
|
693
|
+
|
|
694
|
+
expect(state.executed).toBe(true);
|
|
695
|
+
|
|
696
|
+
arena.dispose();
|
|
697
|
+
ctx.dispose();
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
test("module with strict mode", async () => {
|
|
701
|
+
const ctx = (await getQuickJS()).newContext();
|
|
702
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
703
|
+
|
|
704
|
+
const result = arena.sync({ ok: false });
|
|
705
|
+
arena.expose({ result });
|
|
706
|
+
|
|
707
|
+
// Modules are strict by default
|
|
708
|
+
arena.evalModule(`
|
|
709
|
+
// This would fail in strict mode if we tried: undeclaredVariable = 1;
|
|
710
|
+
result.ok = true;
|
|
711
|
+
`);
|
|
712
|
+
|
|
713
|
+
expect(result.ok).toBe(true);
|
|
714
|
+
|
|
715
|
+
arena.dispose();
|
|
716
|
+
ctx.dispose();
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
test("module returns exported values (0.29+)", async () => {
|
|
720
|
+
const ctx = (await getQuickJS()).newContext();
|
|
721
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
722
|
+
|
|
723
|
+
const exports = arena.evalModule(`
|
|
724
|
+
export const value = 42;
|
|
725
|
+
export const message = "Hello";
|
|
726
|
+
export const obj = { a: 1, b: 2 };
|
|
727
|
+
`);
|
|
728
|
+
|
|
729
|
+
expect(exports.value).toBe(42);
|
|
730
|
+
expect(exports.message).toBe("Hello");
|
|
731
|
+
expect(exports.obj).toEqual({ a: 1, b: 2 });
|
|
732
|
+
|
|
733
|
+
arena.dispose();
|
|
734
|
+
ctx.dispose();
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
test("module returns exported functions (0.29+)", async () => {
|
|
738
|
+
const ctx = (await getQuickJS()).newContext();
|
|
739
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
740
|
+
|
|
741
|
+
const exports = arena.evalModule(`
|
|
742
|
+
export function greet(name) {
|
|
743
|
+
return "Hello, " + name;
|
|
744
|
+
}
|
|
745
|
+
export function add(a, b) {
|
|
746
|
+
return a + b;
|
|
747
|
+
}
|
|
748
|
+
`);
|
|
749
|
+
|
|
750
|
+
expect(exports.greet("World")).toBe("Hello, World");
|
|
751
|
+
expect(exports.add(2, 3)).toBe(5);
|
|
752
|
+
|
|
753
|
+
arena.dispose();
|
|
754
|
+
ctx.dispose();
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
test("module with default export (0.29+)", async () => {
|
|
758
|
+
const ctx = (await getQuickJS()).newContext();
|
|
759
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
760
|
+
|
|
761
|
+
const exports = arena.evalModule(`
|
|
762
|
+
export default function(x) {
|
|
763
|
+
return x * 2;
|
|
764
|
+
}
|
|
765
|
+
`);
|
|
766
|
+
|
|
767
|
+
expect(exports.default(21)).toBe(42);
|
|
768
|
+
|
|
769
|
+
arena.dispose();
|
|
770
|
+
ctx.dispose();
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
test("module with class export (0.29+)", async () => {
|
|
774
|
+
const ctx = (await getQuickJS()).newContext();
|
|
775
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
776
|
+
|
|
777
|
+
// Export objects and static methods from a class
|
|
778
|
+
const exports = arena.evalModule(`
|
|
779
|
+
export class Counter {
|
|
780
|
+
static create(initial = 0) {
|
|
781
|
+
return { count: initial };
|
|
782
|
+
}
|
|
783
|
+
static increment(obj) {
|
|
784
|
+
return ++obj.count;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
`);
|
|
788
|
+
|
|
789
|
+
// Static methods can be called from the host
|
|
790
|
+
const counter = exports.Counter.create(10);
|
|
791
|
+
expect(counter.count).toBe(10);
|
|
792
|
+
expect(exports.Counter.increment(counter)).toBe(11);
|
|
793
|
+
expect(counter.count).toBe(11);
|
|
794
|
+
|
|
795
|
+
arena.dispose();
|
|
796
|
+
ctx.dispose();
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
test("module with top-level await (0.29+)", async () => {
|
|
800
|
+
const ctx = (await getQuickJS()).newContext();
|
|
801
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
802
|
+
|
|
803
|
+
const exportsPromise = arena.evalModule(`
|
|
804
|
+
export const data = await Promise.resolve(123);
|
|
805
|
+
export const message = "loaded";
|
|
806
|
+
`);
|
|
807
|
+
|
|
808
|
+
expect(exportsPromise).toBeInstanceOf(Promise);
|
|
809
|
+
|
|
810
|
+
arena.executePendingJobs();
|
|
811
|
+
|
|
812
|
+
const exports = await exportsPromise;
|
|
813
|
+
expect(exports.data).toBe(123);
|
|
814
|
+
expect(exports.message).toBe("loaded");
|
|
815
|
+
|
|
816
|
+
arena.dispose();
|
|
817
|
+
ctx.dispose();
|
|
818
|
+
});
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
describe("memory management", () => {
|
|
822
|
+
test("getMemoryUsage returns statistics", async () => {
|
|
823
|
+
const ctx = (await getQuickJS()).newContext();
|
|
824
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
825
|
+
|
|
826
|
+
const stats = arena.getMemoryUsage();
|
|
827
|
+
|
|
828
|
+
// Check that key properties exist
|
|
829
|
+
expect(stats).toHaveProperty("memory_used_size");
|
|
830
|
+
expect(stats).toHaveProperty("malloc_limit");
|
|
831
|
+
expect(stats).toHaveProperty("obj_count");
|
|
832
|
+
expect(stats).toHaveProperty("malloc_count");
|
|
833
|
+
|
|
834
|
+
// Memory should be used
|
|
835
|
+
expect(stats.memory_used_size).toBeGreaterThan(0);
|
|
836
|
+
expect(stats.malloc_count).toBeGreaterThan(0);
|
|
837
|
+
|
|
838
|
+
arena.dispose();
|
|
839
|
+
ctx.dispose();
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
test("getMemoryUsage tracks allocations", async () => {
|
|
843
|
+
const ctx = (await getQuickJS()).newContext();
|
|
844
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
845
|
+
|
|
846
|
+
const before = arena.getMemoryUsage();
|
|
847
|
+
|
|
848
|
+
// Allocate some objects
|
|
849
|
+
arena.evalCode(`
|
|
850
|
+
const arr = [];
|
|
851
|
+
for (let i = 0; i < 100; i++) {
|
|
852
|
+
arr.push({ id: i, data: "test".repeat(10) });
|
|
853
|
+
}
|
|
854
|
+
`);
|
|
855
|
+
|
|
856
|
+
const after = arena.getMemoryUsage();
|
|
857
|
+
|
|
858
|
+
// Memory usage should increase
|
|
859
|
+
expect(after.memory_used_size).toBeGreaterThan(before.memory_used_size);
|
|
860
|
+
expect(after.obj_count).toBeGreaterThan(before.obj_count);
|
|
861
|
+
|
|
862
|
+
arena.dispose();
|
|
863
|
+
ctx.dispose();
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
test("dumpMemoryUsage returns formatted string", async () => {
|
|
867
|
+
const ctx = (await getQuickJS()).newContext();
|
|
868
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
869
|
+
|
|
870
|
+
const dump = arena.dumpMemoryUsage();
|
|
871
|
+
|
|
872
|
+
// Should be a non-empty string
|
|
873
|
+
expect(typeof dump).toBe("string");
|
|
874
|
+
expect(dump.length).toBeGreaterThan(0);
|
|
875
|
+
|
|
876
|
+
// Should contain key memory metrics (the format varies)
|
|
877
|
+
expect(dump).toMatch(/memory|malloc/i);
|
|
878
|
+
|
|
879
|
+
arena.dispose();
|
|
880
|
+
ctx.dispose();
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
test("setMemoryLimit enforces memory constraints", async () => {
|
|
884
|
+
const ctx = (await getQuickJS()).newContext();
|
|
885
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
886
|
+
|
|
887
|
+
// Set a low memory limit (100KB)
|
|
888
|
+
arena.setMemoryLimit(100 * 1024);
|
|
889
|
+
|
|
890
|
+
// Verify limit is set
|
|
891
|
+
const stats = arena.getMemoryUsage();
|
|
892
|
+
expect(stats.malloc_limit).toBe(100 * 1024);
|
|
893
|
+
|
|
894
|
+
// Try to allocate too much memory
|
|
895
|
+
expect(() => {
|
|
896
|
+
arena.evalCode(`
|
|
897
|
+
const huge = [];
|
|
898
|
+
for (let i = 0; i < 1000000; i++) {
|
|
899
|
+
huge.push({ data: "x".repeat(1000) });
|
|
900
|
+
}
|
|
901
|
+
`);
|
|
902
|
+
}).toThrow();
|
|
903
|
+
|
|
904
|
+
arena.dispose();
|
|
905
|
+
ctx.dispose();
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
test("setMemoryLimit can be removed with -1", async () => {
|
|
909
|
+
const ctx = (await getQuickJS()).newContext();
|
|
910
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
911
|
+
|
|
912
|
+
// Set a limit
|
|
913
|
+
arena.setMemoryLimit(100 * 1024);
|
|
914
|
+
expect(arena.getMemoryUsage().malloc_limit).toBe(100 * 1024);
|
|
915
|
+
|
|
916
|
+
// Remove the limit
|
|
917
|
+
arena.setMemoryLimit(-1);
|
|
918
|
+
const stats = arena.getMemoryUsage();
|
|
919
|
+
expect(stats.malloc_limit).toBeGreaterThan(100 * 1024);
|
|
920
|
+
|
|
921
|
+
arena.dispose();
|
|
922
|
+
ctx.dispose();
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
test("setMaxStackSize prevents stack overflow", async () => {
|
|
926
|
+
const ctx = (await getQuickJS()).newContext();
|
|
927
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
928
|
+
|
|
929
|
+
// Set a small stack size (256KB)
|
|
930
|
+
arena.setMaxStackSize(256 * 1024);
|
|
931
|
+
|
|
932
|
+
// Try to cause stack overflow with deep recursion
|
|
933
|
+
expect(() => {
|
|
934
|
+
arena.evalCode(`
|
|
935
|
+
function recurse(n) {
|
|
936
|
+
if (n > 0) return recurse(n - 1);
|
|
937
|
+
return n;
|
|
938
|
+
}
|
|
939
|
+
recurse(100000);
|
|
940
|
+
`);
|
|
941
|
+
}).toThrow();
|
|
942
|
+
|
|
943
|
+
arena.dispose();
|
|
944
|
+
ctx.dispose();
|
|
945
|
+
});
|
|
946
|
+
|
|
947
|
+
test("setMaxStackSize can be removed with 0", async () => {
|
|
948
|
+
const ctx = (await getQuickJS()).newContext();
|
|
949
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
950
|
+
|
|
951
|
+
// Set a very small stack
|
|
952
|
+
arena.setMaxStackSize(128 * 1024);
|
|
953
|
+
|
|
954
|
+
// This should fail with small stack
|
|
955
|
+
expect(() => {
|
|
956
|
+
arena.evalCode(`
|
|
957
|
+
function recurse(n) {
|
|
958
|
+
if (n > 0) return recurse(n - 1);
|
|
959
|
+
return n;
|
|
960
|
+
}
|
|
961
|
+
recurse(10000);
|
|
962
|
+
`);
|
|
963
|
+
}).toThrow();
|
|
964
|
+
|
|
965
|
+
// Remove the limit
|
|
966
|
+
arena.setMaxStackSize(0);
|
|
967
|
+
|
|
968
|
+
// Now it should work (or at least get further)
|
|
969
|
+
const result = arena.evalCode(`
|
|
970
|
+
function recurse(n) {
|
|
971
|
+
if (n > 0) return recurse(n - 1);
|
|
972
|
+
return n;
|
|
973
|
+
}
|
|
974
|
+
recurse(1000);
|
|
975
|
+
`);
|
|
976
|
+
|
|
977
|
+
expect(result).toBe(0);
|
|
978
|
+
|
|
979
|
+
arena.dispose();
|
|
980
|
+
ctx.dispose();
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
test("memory limits work with marshaling", async () => {
|
|
984
|
+
const ctx = (await getQuickJS()).newContext();
|
|
985
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
986
|
+
|
|
987
|
+
// Set limit
|
|
988
|
+
arena.setMemoryLimit(200 * 1024);
|
|
989
|
+
|
|
990
|
+
const data = arena.sync({ items: [] as any[] });
|
|
991
|
+
arena.expose({ data });
|
|
992
|
+
|
|
993
|
+
// Should be able to add reasonable data
|
|
994
|
+
arena.evalCode(`
|
|
995
|
+
for (let i = 0; i < 10; i++) {
|
|
996
|
+
data.items.push({ id: i });
|
|
997
|
+
}
|
|
998
|
+
`);
|
|
999
|
+
|
|
1000
|
+
expect(data.items.length).toBe(10);
|
|
1001
|
+
|
|
1002
|
+
// But not unlimited data
|
|
1003
|
+
expect(() => {
|
|
1004
|
+
arena.evalCode(`
|
|
1005
|
+
for (let i = 0; i < 100000; i++) {
|
|
1006
|
+
data.items.push({ id: i, data: "x".repeat(1000) });
|
|
1007
|
+
}
|
|
1008
|
+
`);
|
|
1009
|
+
}).toThrow();
|
|
1010
|
+
|
|
1011
|
+
arena.dispose();
|
|
1012
|
+
ctx.dispose();
|
|
1013
|
+
});
|
|
1014
|
+
});
|
|
1015
|
+
|
|
1016
|
+
describe("intrinsics configuration", () => {
|
|
1017
|
+
test("intrinsics can be configured when creating context", async () => {
|
|
1018
|
+
const quickjs = await getQuickJS();
|
|
1019
|
+
const runtime = quickjs.newRuntime();
|
|
1020
|
+
|
|
1021
|
+
// Example: disable eval for sandboxing
|
|
1022
|
+
const ctx = runtime.newContext({ intrinsics: { Eval: false } });
|
|
1023
|
+
const arena = new Arena(ctx, { isMarshalable: true });
|
|
1024
|
+
|
|
1025
|
+
// This test demonstrates that intrinsics are configured at context creation
|
|
1026
|
+
// The actual restrictions would be enforced by quickjs-emscripten
|
|
1027
|
+
expect(arena).toBeDefined();
|
|
1028
|
+
expect(arena.context).toBeDefined();
|
|
1029
|
+
|
|
1030
|
+
arena.dispose();
|
|
1031
|
+
ctx.dispose();
|
|
1032
|
+
runtime.dispose();
|
|
1033
|
+
});
|
|
1034
|
+
});
|