jseption 0.0.4 → 0.0.5

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/README.md CHANGED
@@ -206,6 +206,36 @@ run when they settle) and preserves shared references and cycles. `fromGuest` do
206
206
  reverse, turning guest functions into host functions that call into the guest. See
207
207
  `examples/fetch.ts`.
208
208
 
209
+ ### Live host objects (the membrane)
210
+
211
+ `exposeLive` hands the guest a live view of a host API instead of a copy. Every host
212
+ object or function reachable from the root crosses as a proxy created on first use;
213
+ each operation is forwarded to the host object and its result converted the same way,
214
+ so nested objects, returned instances and constructed objects are proxied too:
215
+
216
+ ```ts
217
+ import { exposeLive } from 'jseption';
218
+
219
+ exposeLive(ctx, 'Intl', Intl); // the page's real Intl, read-only
220
+ JS_Eval(ctx, `new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit', timeZone: 'UTC' })
221
+ .format(new Date(0))`, 'guest.js', JS_EVAL_TYPE_GLOBAL); // '12:00 AM'
222
+
223
+ exposeLive(ctx, 'store', store, { writable: true, allow: (target, key) => key !== 'internal' });
224
+ ```
225
+
226
+ Primitives cross as values, host arrays as snapshot guest arrays, `Date`/`RegExp`/typed
227
+ arrays/errors as copies, promises as guest promises; guest arguments are copied
228
+ (`fromGuest`), a proxy passed back is unwrapped to its host object, and guest callbacks
229
+ become host functions. The sandbox rules are always on: host intrinsics (`Function`,
230
+ `eval`, `globalThis`, `Object`, `Reflect`, `Proxy`, the intrinsic prototypes, ...) never
231
+ cross; `constructor`, `prototype`, `__proto__`, `caller`, `callee` and `arguments` read as
232
+ `undefined`; a proxy's prototype is the guest's `Object.prototype`; host functions are
233
+ only callable and constructible; host exceptions become guest errors of the same type;
234
+ writes need `writable: true`. The membrane cannot see inside host code, so expose narrow
235
+ roots (`Intl`, `TextEncoder`, a purpose-built facade), never broad objects such as the
236
+ DOM or anything that reaches host globals. See `docs/MEMBRANE.md` for the model, the
237
+ rules and the limits.
238
+
209
239
  ## Layout
210
240
 
211
241
  ```
@@ -224,6 +254,7 @@ src/std.ts print / console / std / os helpers for the CLI (subset of qu
224
254
  src/qjs.ts command line interpreter
225
255
  src/dump.ts bytecode disassembler
226
256
  src/embed.ts host <-> guest value marshalling (expose, toGuest, fromGuest, promises)
257
+ src/membrane.ts live host objects for the guest (exposeLive, toGuestLive)
227
258
  examples/ embedding examples (fetch facade)
228
259
  bench/ benchmark programs and runners (host vs compiled vs interpreted)
229
260
  tests/ bun tests, including the QuickJS test suite files in tests/qjs/
package/dist/embed.d.ts CHANGED
@@ -13,6 +13,11 @@ export declare function guestErrorToHost(ctx: JSContext, exc: JSValue): Error;
13
13
  export declare function toGuest(ctx: JSContext, value: unknown, opts?: ToGuestOptions): JSValue;
14
14
  export declare function hostFunction(ctx: JSContext, fn: (...args: any[]) => unknown, name?: string, length?: number, opts?: ToGuestOptions): JSValue;
15
15
  export declare function hostPromise(ctx: JSContext, p: PromiseLike<unknown>, opts?: ToGuestOptions): JSValue;
16
+ export declare function hostPromiseWith(ctx: JSContext, p: PromiseLike<unknown>, resolve: (v: unknown) => JSValue, reject: (e: unknown) => JSValue): JSValue;
16
17
  export declare function expose(ctx: JSContext, name: string, value: unknown, opts?: ToGuestOptions): void;
17
18
  export declare function fromGuest(ctx: JSContext, value: JSValue): unknown;
19
+ export declare const FROM_GUEST_DEFAULT: unique symbol;
20
+ export type FromGuestHook = (v: JSValue) => unknown;
21
+ export declare function fromGuestWith(ctx: JSContext, value: JSValue, hook: FromGuestHook): unknown;
18
22
  export declare function guestPromiseToHost(ctx: JSContext, promise: JSValue): Promise<unknown>;
23
+ export declare function guestPromiseToHostWith(ctx: JSContext, promise: JSValue, convert: (v: JSValue) => unknown, convertRejection: (e: JSValue) => unknown): Promise<unknown>;
package/dist/embed.js CHANGED
@@ -172,23 +172,30 @@ export function hostFunction(ctx, fn, name = fn.name || 'hostFunction', length =
172
172
  /* a guest promise that settles when the host promise does; guest jobs are
173
173
  run after the settlement so `await` continuations execute promptly */
174
174
  export function hostPromise(ctx, p, opts = {}) {
175
+ return hostPromiseWith(ctx, p, v => toGuest(ctx, v, opts), e => toGuest(ctx, e, opts));
176
+ }
177
+ /* hostPromise with the conversions supplied by the caller (the membrane
178
+ converts results live); `reject` converts a rejection reason or an
179
+ exception thrown by `resolve` */
180
+ export function hostPromiseWith(ctx, p, resolve, reject) {
175
181
  const funcs = [undefined, undefined];
176
182
  const promise = JS_NewPromiseCapability(ctx, funcs);
177
183
  if (JS_IsException(promise))
178
184
  throwGuestException(ctx);
179
- const settle = (fn, v) => {
185
+ const settle = (ok, v) => {
186
+ let fn = ok ? funcs[0] : funcs[1];
180
187
  let g;
181
188
  try {
182
- g = toGuest(ctx, v, opts);
189
+ g = ok ? resolve(v) : reject(v);
183
190
  }
184
191
  catch (e) {
185
192
  fn = funcs[1];
186
- g = toGuest(ctx, e, opts);
193
+ g = reject(e);
187
194
  }
188
195
  JS_Call(ctx, fn, undefined, [g]);
189
196
  drainJobs(ctx);
190
197
  };
191
- p.then(v => settle(funcs[0], v), e => settle(funcs[1], e));
198
+ p.then(v => settle(true, v), e => settle(false, e));
192
199
  return promise;
193
200
  }
194
201
  /* define a global variable in the guest */
@@ -200,9 +207,21 @@ export function expose(ctx, name, value, opts = {}) {
200
207
  functions become host functions (that call into the guest), guest
201
208
  promises become host promises, errors become host Errors */
202
209
  export function fromGuest(ctx, value) {
203
- return fromGuestRec(ctx, value, new Map());
210
+ return fromGuestRec(ctx, value, new Map(), undefined);
211
+ }
212
+ /* returned by a fromGuestWith hook to let the default conversion handle a value */
213
+ export const FROM_GUEST_DEFAULT = Symbol('fromGuest default');
214
+ /* fromGuest with a hook that is offered every value first, at every depth
215
+ (the membrane unwraps its proxies and wraps guest functions this way) */
216
+ export function fromGuestWith(ctx, value, hook) {
217
+ return fromGuestRec(ctx, value, new Map(), hook);
204
218
  }
205
- function fromGuestRec(ctx, v, seen) {
219
+ function fromGuestRec(ctx, v, seen, hook) {
220
+ if (hook !== undefined) {
221
+ const r = hook(v);
222
+ if (r !== FROM_GUEST_DEFAULT)
223
+ return r;
224
+ }
206
225
  if (typeof v === 'function') {
207
226
  return (...args) => {
208
227
  const r = JS_Call(ctx, v, undefined, args.map(a => toGuest(ctx, a)));
@@ -230,14 +249,14 @@ function fromGuestRec(ctx, v, seen) {
230
249
  const m = new Map();
231
250
  seen.set(v, m);
232
251
  for (const [k, val] of Map.prototype.entries.call(o))
233
- m.set(fromGuestRec(ctx, k, seen), fromGuestRec(ctx, val, seen));
252
+ m.set(fromGuestRec(ctx, k, seen, hook), fromGuestRec(ctx, val, seen, hook));
234
253
  return m;
235
254
  }
236
255
  case 35 /* JSClassID.SET */: {
237
256
  const s = new Set();
238
257
  seen.set(v, s);
239
258
  for (const val of Set.prototype.values.call(o))
240
- s.add(fromGuestRec(ctx, val, seen));
259
+ s.add(fromGuestRec(ctx, val, seen, hook));
241
260
  return s;
242
261
  }
243
262
  case 19 /* JSClassID.ARRAY_BUFFER */:
@@ -253,7 +272,7 @@ function fromGuestRec(ctx, v, seen) {
253
272
  const a = [];
254
273
  seen.set(v, a);
255
274
  for (let i = 0; i < o.length; i++)
256
- a[i] = fromGuestRec(ctx, o[i], seen);
275
+ a[i] = fromGuestRec(ctx, o[i], seen, hook);
257
276
  return a;
258
277
  }
259
278
  const r = {};
@@ -262,16 +281,29 @@ function fromGuestRec(ctx, v, seen) {
262
281
  const d = Reflect.getOwnPropertyDescriptor(o, k);
263
282
  if (!d.enumerable)
264
283
  continue;
265
- r[k] = fromGuestRec(ctx, o[k], seen);
284
+ r[k] = fromGuestRec(ctx, o[k], seen, hook);
266
285
  }
267
286
  return r;
268
287
  }
269
288
  /* a host promise that settles when the guest promise does */
270
289
  export function guestPromiseToHost(ctx, promise) {
290
+ return guestPromiseToHostWith(ctx, promise, v => fromGuest(ctx, v), e => fromGuestRejection(ctx, e));
291
+ }
292
+ /* guestPromiseToHost with the conversions supplied by the caller */
293
+ export function guestPromiseToHostWith(ctx, promise, convert, convertRejection) {
271
294
  return new Promise((resolve, reject) => {
272
295
  const then = JS_GetPropertyStr(ctx, promise, 'then');
273
- const onFul = JS_NewCFunction(ctx, (_c, _t, argv) => { resolve(fromGuest(ctx, argv[0])); return undefined; }, 'resolve', 1);
274
- const onRej = JS_NewCFunction(ctx, (_c, _t, argv) => { reject(fromGuestRejection(ctx, argv[0])); return undefined; }, 'reject', 1);
296
+ const settle = (fn, conv, v) => {
297
+ try {
298
+ fn(conv(v));
299
+ }
300
+ catch (e) {
301
+ reject(e);
302
+ }
303
+ return undefined;
304
+ };
305
+ const onFul = JS_NewCFunction(ctx, (_c, _t, argv) => settle(resolve, convert, argv[0]), 'resolve', 1);
306
+ const onRej = JS_NewCFunction(ctx, (_c, _t, argv) => settle(reject, convertRejection, argv[0]), 'reject', 1);
275
307
  const r = JS_Call(ctx, then, promise, [onFul, onRej]);
276
308
  if (JS_IsException(r))
277
309
  reject(guestErrorToHost(ctx, JS_GetException(ctx)));
package/dist/embed.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"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","sourcesContent":["/* Embedding helpers: moving values between the host and the guest.\n *\n * Guest values are host values, but the sandbox requires that nothing the\n * guest can reach has a host intrinsic in its prototype chain. A host\n * object therefore cannot be handed to the guest as is: `toGuest` copies\n * plain data into guest objects, wraps host functions in guest functions,\n * and bridges host promises to guest promises. `fromGuest` does the\n * reverse so the host gets ordinary host objects (and can call guest\n * functions / await guest promises). Primitives cross unchanged. */\n\nimport {\n JSContext, JSValue, JSClassID, JS_IsException, JS_IsObject, JS_GetClassID, JS_GetAnyOpaque,\n JS_NewObject, JS_NewArrayFrom, JS_NewCFunction, JS_Call, JS_CallConstructor, JS_Throw,\n JS_GetException, JS_GetPropertyStr, JS_SetPropertyStr, JS_ToString, JS_NewErrorNative,\n JS_ExecutePendingJob, JS_IsJobPending, js_meta,\n} from './quickjs.ts';\nimport { JSErrorEnum } from './values.ts';\nimport { JS_NewPromiseCapability } from './builtins/promise.ts';\nimport { JS_NewDate } from './builtins/date.ts';\nimport { JS_NewArrayBufferCopy } from './builtins/typedarray.ts';\n\nexport interface ToGuestOptions {\n /** convert a host value the default rules reject (class instances); return\n * undefined to fall through to the TypeError */\n custom?: (ctx: JSContext, value: object) => JSValue | undefined;\n /** deep-convert the arguments guest code passes to a wrapped host function\n * into plain host values (default: pass the guest values through) */\n convertArgs?: boolean;\n}\n\nconst HOST_INTRINSIC_PROTOS = new Set<object>([\n Object.prototype, Array.prototype, Function.prototype, Error.prototype, Date.prototype, RegExp.prototype,\n Map.prototype, Set.prototype, Promise.prototype, ArrayBuffer.prototype,\n Object.getPrototypeOf(Uint8Array.prototype),\n]);\n\n/* true if the value is already safe to hand to the guest: engine metadata or\n a prototype chain that never reaches a host intrinsic */\nexport function isGuestValue(v: unknown): boolean {\n if (typeof v === 'function' || (typeof v === 'object' && v !== null)) {\n if (js_meta.has(v as object)) return true;\n let p: object | null = v as object;\n while (p !== null) {\n if (HOST_INTRINSIC_PROTOS.has(p) || p === globalThis) return false;\n p = Object.getPrototypeOf(p);\n }\n return true;\n }\n return true;\n}\n\n/* run the guest job queue (promise reactions) until it is empty */\nexport function drainJobs(ctx: JSContext): void {\n const rt = ctx.rt;\n const pctx = { ctx: null as JSContext | null };\n while (JS_IsJobPending(rt)) JS_ExecutePendingJob(rt, pctx);\n}\n\nfunction guestCtor(ctx: JSContext, name: string): JSValue {\n return JS_GetPropertyStr(ctx, ctx.global_obj, name);\n}\n\nfunction throwGuestException(ctx: JSContext): never {\n throw guestErrorToHost(ctx, JS_GetException(ctx));\n}\n\n/* convert a guest exception value into a host Error for host callers */\nexport function guestErrorToHost(ctx: JSContext, exc: JSValue): Error {\n if (JS_IsObject(exc) && JS_GetClassID(exc) === JSClassID.ERROR) {\n const o = exc as any;\n const err = new Error(String(o.message ?? ''));\n err.name = String(o.name ?? 'Error');\n if (typeof o.stack === 'string') (err as any).guestStack = o.stack;\n return err;\n }\n const err = new Error(typeof exc === 'string' ? exc : String(JS_ToString(ctx, exc)));\n (err as any).guestValue = exc;\n return err;\n}\n\nconst ERROR_KINDS: Record<string, JSErrorEnum> = {\n EvalError: JSErrorEnum.EVAL_ERROR, RangeError: JSErrorEnum.RANGE_ERROR, ReferenceError: JSErrorEnum.REFERENCE_ERROR,\n SyntaxError: JSErrorEnum.SYNTAX_ERROR, TypeError: JSErrorEnum.TYPE_ERROR, URIError: JSErrorEnum.URI_ERROR,\n};\n\n/* host value -> guest value */\nexport function toGuest(ctx: JSContext, value: unknown, opts: ToGuestOptions = {}): JSValue {\n return toGuestRec(ctx, value, opts, new Map());\n}\n\nfunction toGuestRec(ctx: JSContext, v: unknown, opts: ToGuestOptions, seen: Map<object, JSValue>): JSValue {\n switch (typeof v) {\n case 'undefined': case 'boolean': case 'number': case 'string': case 'bigint': case 'symbol':\n return v as JSValue;\n case 'function':\n if (isGuestValue(v)) return v as JSValue;\n return hostFunction(ctx, v as (...args: any[]) => unknown, (v as Function).name, (v as Function).length, opts);\n }\n if (v === null) return null;\n const o = v as any;\n if (isGuestValue(o)) return o;\n const cached = seen.get(o);\n if (cached !== undefined) return cached;\n const remember = (g: JSValue): JSValue => { seen.set(o, g); return g; };\n\n if (typeof o.then === 'function') return remember(hostPromise(ctx, o, opts));\n if (Array.isArray(o)) {\n const arr = JS_NewArrayFrom(ctx, []) as any;\n seen.set(o, arr);\n for (let i = 0; i < o.length; i++) arr[i] = toGuestRec(ctx, o[i], opts, seen);\n return arr;\n }\n if (o instanceof Date) return remember(JS_NewDate(ctx, o.getTime()));\n if (o instanceof RegExp) return remember(construct(ctx, 'RegExp', [o.source, o.flags]));\n if (o instanceof Error) {\n const kind = ERROR_KINDS[o.name] ?? JSErrorEnum.PLAIN_ERROR;\n const err = JS_NewErrorNative(ctx, kind, String(o.message));\n return remember(err);\n }\n if (o instanceof Map) {\n const m = construct(ctx, 'Map', []) as any;\n seen.set(o, m);\n for (const [k, val] of o) m.set(toGuestRec(ctx, k, opts, seen), toGuestRec(ctx, val, opts, seen));\n return m;\n }\n if (o instanceof Set) {\n const s = construct(ctx, 'Set', []) as any;\n seen.set(o, s);\n for (const val of o) s.add(toGuestRec(ctx, val, opts, seen));\n return s;\n }\n if (o instanceof ArrayBuffer) return remember(JS_NewArrayBufferCopy(ctx, new Uint8Array(o)));\n if (ArrayBuffer.isView(o)) {\n const buf = JS_NewArrayBufferCopy(ctx, new Uint8Array(o.buffer, o.byteOffset, o.byteLength));\n const name = (o as any)[Symbol.toStringTag] as string; /* \"Uint8Array\", \"DataView\", ... */\n return remember(construct(ctx, name, [buf]));\n }\n const proto = Object.getPrototypeOf(o);\n if (proto === Object.prototype || proto === null) {\n const g = JS_NewObject(ctx) as any;\n seen.set(o, g);\n for (const k of Reflect.ownKeys(o)) {\n const d = Reflect.getOwnPropertyDescriptor(o, k)!;\n if (!d.enumerable) continue;\n g[k] = toGuestRec(ctx, o[k], opts, seen);\n }\n return g;\n }\n if (opts.custom) {\n const r = opts.custom(ctx, o);\n if (r !== undefined) return remember(r);\n }\n throw new TypeError(`toGuest: cannot pass a host ${proto?.constructor?.name ?? 'object'} to the guest; ` +\n 'pass plain data, functions, promises, or provide a custom converter');\n}\n\nfunction construct(ctx: JSContext, ctorName: string, args: unknown[]): JSValue {\n const r = JS_CallConstructor(ctx, guestCtor(ctx, ctorName), args as JSValue[]);\n if (JS_IsException(r)) throwGuestException(ctx);\n return r;\n}\n\n/* a guest function that calls the host function. Host exceptions become\n guest errors; host return values (including promises) are converted. */\nexport function hostFunction(ctx: JSContext, fn: (...args: any[]) => unknown, name = fn.name || 'hostFunction',\n length = fn.length, opts: ToGuestOptions = {}): JSValue {\n return JS_NewCFunction(ctx, (ctx2: JSContext, this_val: JSValue, argv: JSValue[]) => {\n try {\n const args = opts.convertArgs ? argv.map(a => fromGuest(ctx2, a)) : argv;\n const self = opts.convertArgs ? fromGuest(ctx2, this_val) : this_val;\n return toGuest(ctx2, fn.apply(self, args), opts);\n } catch (e) {\n return JS_Throw(ctx2, toGuest(ctx2, e, opts));\n }\n }, name, length);\n}\n\n/* a guest promise that settles when the host promise does; guest jobs are\n run after the settlement so `await` continuations execute promptly */\nexport function hostPromise(ctx: JSContext, p: PromiseLike<unknown>, opts: ToGuestOptions = {}): JSValue {\n const funcs: [JSValue, JSValue] = [undefined, undefined];\n const promise = JS_NewPromiseCapability(ctx, funcs);\n if (JS_IsException(promise)) throwGuestException(ctx);\n const settle = (fn: JSValue, v: unknown) => {\n let g: JSValue;\n try { g = toGuest(ctx, v, opts); } catch (e) { fn = funcs[1]; g = toGuest(ctx, e, opts); }\n JS_Call(ctx, fn, undefined, [g]);\n drainJobs(ctx);\n };\n p.then(v => settle(funcs[0], v), e => settle(funcs[1], e));\n return promise;\n}\n\n/* define a global variable in the guest */\nexport function expose(ctx: JSContext, name: string, value: unknown, opts: ToGuestOptions = {}): void {\n if (JS_SetPropertyStr(ctx, ctx.global_obj, name, toGuest(ctx, value, opts)) < 0) throwGuestException(ctx);\n}\n\n/* guest value -> plain host value: objects and arrays are copied, guest\n functions become host functions (that call into the guest), guest\n promises become host promises, errors become host Errors */\nexport function fromGuest(ctx: JSContext, value: JSValue): unknown {\n return fromGuestRec(ctx, value, new Map());\n}\n\nfunction fromGuestRec(ctx: JSContext, v: JSValue, seen: Map<object, unknown>): unknown {\n if (typeof v === 'function') {\n return (...args: unknown[]) => {\n const r = JS_Call(ctx, v, undefined, args.map(a => toGuest(ctx, a)));\n if (JS_IsException(r)) throwGuestException(ctx);\n return fromGuest(ctx, r);\n };\n }\n if (typeof v !== 'object' || v === null) return v;\n const cached = seen.get(v);\n if (cached !== undefined) return cached;\n const o = v as any;\n switch (JS_GetClassID(v)) {\n case JSClassID.PROMISE:\n return guestPromiseToHost(ctx, v);\n case JSClassID.DATE:\n return new Date(JS_GetAnyOpaque(v) as number);\n case JSClassID.ERROR:\n return guestErrorToHost(ctx, v);\n case JSClassID.REGEXP:\n return new RegExp(o.source, o.flags);\n case JSClassID.MAP: {\n const m = new Map(); seen.set(v, m);\n for (const [k, val] of Map.prototype.entries.call(o)) m.set(fromGuestRec(ctx, k, seen), fromGuestRec(ctx, val, seen));\n return m;\n }\n case JSClassID.SET: {\n const s = new Set(); seen.set(v, s);\n for (const val of Set.prototype.values.call(o)) s.add(fromGuestRec(ctx, val, seen));\n return s;\n }\n case JSClassID.ARRAY_BUFFER:\n /* the guest object is the host ArrayBuffer re-prototyped: copy it */\n return new Uint8Array(o as ArrayBuffer).slice().buffer;\n }\n if (ArrayBuffer.isView(o)) {\n /* guest typed arrays are host views re-prototyped: copy with the host constructor */\n const Ctor = (globalThis as any)[(o as any)[Symbol.toStringTag]];\n return Ctor ? new Ctor(o as any) : new Uint8Array(o as any);\n }\n if (Array.isArray(o)) {\n const a: unknown[] = []; seen.set(v, a);\n for (let i = 0; i < o.length; i++) a[i] = fromGuestRec(ctx, o[i], seen);\n return a;\n }\n const r: Record<PropertyKey, unknown> = {}; seen.set(v, r);\n for (const k of Reflect.ownKeys(o)) {\n const d = Reflect.getOwnPropertyDescriptor(o, k)!;\n if (!d.enumerable) continue;\n r[k] = fromGuestRec(ctx, o[k], seen);\n }\n return r;\n}\n\n/* a host promise that settles when the guest promise does */\nexport function guestPromiseToHost(ctx: JSContext, promise: JSValue): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const then = JS_GetPropertyStr(ctx, promise, 'then');\n const onFul = JS_NewCFunction(ctx, (_c, _t, argv) => { resolve(fromGuest(ctx, argv[0])); return undefined; }, 'resolve', 1);\n const onRej = JS_NewCFunction(ctx, (_c, _t, argv) => { reject(fromGuestRejection(ctx, argv[0])); return undefined; }, 'reject', 1);\n const r = JS_Call(ctx, then, promise, [onFul, onRej]);\n if (JS_IsException(r)) reject(guestErrorToHost(ctx, JS_GetException(ctx)));\n drainJobs(ctx);\n });\n}\n\nfunction fromGuestRejection(ctx: JSContext, reason: JSValue): unknown {\n if (JS_IsObject(reason) && JS_GetClassID(reason) === JSClassID.ERROR) return guestErrorToHost(ctx, reason);\n return fromGuest(ctx, reason);\n}\n"]}
1
+ {"version":3,"file":"embed.js","sourceRoot":"","sources":["../src/embed.ts"],"names":[],"mappings":"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","sourcesContent":["/* Embedding helpers: moving values between the host and the guest.\n *\n * Guest values are host values, but the sandbox requires that nothing the\n * guest can reach has a host intrinsic in its prototype chain. A host\n * object therefore cannot be handed to the guest as is: `toGuest` copies\n * plain data into guest objects, wraps host functions in guest functions,\n * and bridges host promises to guest promises. `fromGuest` does the\n * reverse so the host gets ordinary host objects (and can call guest\n * functions / await guest promises). Primitives cross unchanged. */\n\nimport {\n JSContext, JSValue, JSClassID, JS_IsException, JS_IsObject, JS_GetClassID, JS_GetAnyOpaque,\n JS_NewObject, JS_NewArrayFrom, JS_NewCFunction, JS_Call, JS_CallConstructor, JS_Throw,\n JS_GetException, JS_GetPropertyStr, JS_SetPropertyStr, JS_ToString, JS_NewErrorNative,\n JS_ExecutePendingJob, JS_IsJobPending, js_meta,\n} from './quickjs.ts';\nimport { JSErrorEnum } from './values.ts';\nimport { JS_NewPromiseCapability } from './builtins/promise.ts';\nimport { JS_NewDate } from './builtins/date.ts';\nimport { JS_NewArrayBufferCopy } from './builtins/typedarray.ts';\n\nexport interface ToGuestOptions {\n /** convert a host value the default rules reject (class instances); return\n * undefined to fall through to the TypeError */\n custom?: (ctx: JSContext, value: object) => JSValue | undefined;\n /** deep-convert the arguments guest code passes to a wrapped host function\n * into plain host values (default: pass the guest values through) */\n convertArgs?: boolean;\n}\n\nconst HOST_INTRINSIC_PROTOS = new Set<object>([\n Object.prototype, Array.prototype, Function.prototype, Error.prototype, Date.prototype, RegExp.prototype,\n Map.prototype, Set.prototype, Promise.prototype, ArrayBuffer.prototype,\n Object.getPrototypeOf(Uint8Array.prototype),\n]);\n\n/* true if the value is already safe to hand to the guest: engine metadata or\n a prototype chain that never reaches a host intrinsic */\nexport function isGuestValue(v: unknown): boolean {\n if (typeof v === 'function' || (typeof v === 'object' && v !== null)) {\n if (js_meta.has(v as object)) return true;\n let p: object | null = v as object;\n while (p !== null) {\n if (HOST_INTRINSIC_PROTOS.has(p) || p === globalThis) return false;\n p = Object.getPrototypeOf(p);\n }\n return true;\n }\n return true;\n}\n\n/* run the guest job queue (promise reactions) until it is empty */\nexport function drainJobs(ctx: JSContext): void {\n const rt = ctx.rt;\n const pctx = { ctx: null as JSContext | null };\n while (JS_IsJobPending(rt)) JS_ExecutePendingJob(rt, pctx);\n}\n\nfunction guestCtor(ctx: JSContext, name: string): JSValue {\n return JS_GetPropertyStr(ctx, ctx.global_obj, name);\n}\n\nfunction throwGuestException(ctx: JSContext): never {\n throw guestErrorToHost(ctx, JS_GetException(ctx));\n}\n\n/* convert a guest exception value into a host Error for host callers */\nexport function guestErrorToHost(ctx: JSContext, exc: JSValue): Error {\n if (JS_IsObject(exc) && JS_GetClassID(exc) === JSClassID.ERROR) {\n const o = exc as any;\n const err = new Error(String(o.message ?? ''));\n err.name = String(o.name ?? 'Error');\n if (typeof o.stack === 'string') (err as any).guestStack = o.stack;\n return err;\n }\n const err = new Error(typeof exc === 'string' ? exc : String(JS_ToString(ctx, exc)));\n (err as any).guestValue = exc;\n return err;\n}\n\nconst ERROR_KINDS: Record<string, JSErrorEnum> = {\n EvalError: JSErrorEnum.EVAL_ERROR, RangeError: JSErrorEnum.RANGE_ERROR, ReferenceError: JSErrorEnum.REFERENCE_ERROR,\n SyntaxError: JSErrorEnum.SYNTAX_ERROR, TypeError: JSErrorEnum.TYPE_ERROR, URIError: JSErrorEnum.URI_ERROR,\n};\n\n/* host value -> guest value */\nexport function toGuest(ctx: JSContext, value: unknown, opts: ToGuestOptions = {}): JSValue {\n return toGuestRec(ctx, value, opts, new Map());\n}\n\nfunction toGuestRec(ctx: JSContext, v: unknown, opts: ToGuestOptions, seen: Map<object, JSValue>): JSValue {\n switch (typeof v) {\n case 'undefined': case 'boolean': case 'number': case 'string': case 'bigint': case 'symbol':\n return v as JSValue;\n case 'function':\n if (isGuestValue(v)) return v as JSValue;\n return hostFunction(ctx, v as (...args: any[]) => unknown, (v as Function).name, (v as Function).length, opts);\n }\n if (v === null) return null;\n const o = v as any;\n if (isGuestValue(o)) return o;\n const cached = seen.get(o);\n if (cached !== undefined) return cached;\n const remember = (g: JSValue): JSValue => { seen.set(o, g); return g; };\n\n if (typeof o.then === 'function') return remember(hostPromise(ctx, o, opts));\n if (Array.isArray(o)) {\n const arr = JS_NewArrayFrom(ctx, []) as any;\n seen.set(o, arr);\n for (let i = 0; i < o.length; i++) arr[i] = toGuestRec(ctx, o[i], opts, seen);\n return arr;\n }\n if (o instanceof Date) return remember(JS_NewDate(ctx, o.getTime()));\n if (o instanceof RegExp) return remember(construct(ctx, 'RegExp', [o.source, o.flags]));\n if (o instanceof Error) {\n const kind = ERROR_KINDS[o.name] ?? JSErrorEnum.PLAIN_ERROR;\n const err = JS_NewErrorNative(ctx, kind, String(o.message));\n return remember(err);\n }\n if (o instanceof Map) {\n const m = construct(ctx, 'Map', []) as any;\n seen.set(o, m);\n for (const [k, val] of o) m.set(toGuestRec(ctx, k, opts, seen), toGuestRec(ctx, val, opts, seen));\n return m;\n }\n if (o instanceof Set) {\n const s = construct(ctx, 'Set', []) as any;\n seen.set(o, s);\n for (const val of o) s.add(toGuestRec(ctx, val, opts, seen));\n return s;\n }\n if (o instanceof ArrayBuffer) return remember(JS_NewArrayBufferCopy(ctx, new Uint8Array(o)));\n if (ArrayBuffer.isView(o)) {\n const buf = JS_NewArrayBufferCopy(ctx, new Uint8Array(o.buffer, o.byteOffset, o.byteLength));\n const name = (o as any)[Symbol.toStringTag] as string; /* \"Uint8Array\", \"DataView\", ... */\n return remember(construct(ctx, name, [buf]));\n }\n const proto = Object.getPrototypeOf(o);\n if (proto === Object.prototype || proto === null) {\n const g = JS_NewObject(ctx) as any;\n seen.set(o, g);\n for (const k of Reflect.ownKeys(o)) {\n const d = Reflect.getOwnPropertyDescriptor(o, k)!;\n if (!d.enumerable) continue;\n g[k] = toGuestRec(ctx, o[k], opts, seen);\n }\n return g;\n }\n if (opts.custom) {\n const r = opts.custom(ctx, o);\n if (r !== undefined) return remember(r);\n }\n throw new TypeError(`toGuest: cannot pass a host ${proto?.constructor?.name ?? 'object'} to the guest; ` +\n 'pass plain data, functions, promises, or provide a custom converter');\n}\n\nfunction construct(ctx: JSContext, ctorName: string, args: unknown[]): JSValue {\n const r = JS_CallConstructor(ctx, guestCtor(ctx, ctorName), args as JSValue[]);\n if (JS_IsException(r)) throwGuestException(ctx);\n return r;\n}\n\n/* a guest function that calls the host function. Host exceptions become\n guest errors; host return values (including promises) are converted. */\nexport function hostFunction(ctx: JSContext, fn: (...args: any[]) => unknown, name = fn.name || 'hostFunction',\n length = fn.length, opts: ToGuestOptions = {}): JSValue {\n return JS_NewCFunction(ctx, (ctx2: JSContext, this_val: JSValue, argv: JSValue[]) => {\n try {\n const args = opts.convertArgs ? argv.map(a => fromGuest(ctx2, a)) : argv;\n const self = opts.convertArgs ? fromGuest(ctx2, this_val) : this_val;\n return toGuest(ctx2, fn.apply(self, args), opts);\n } catch (e) {\n return JS_Throw(ctx2, toGuest(ctx2, e, opts));\n }\n }, name, length);\n}\n\n/* a guest promise that settles when the host promise does; guest jobs are\n run after the settlement so `await` continuations execute promptly */\nexport function hostPromise(ctx: JSContext, p: PromiseLike<unknown>, opts: ToGuestOptions = {}): JSValue {\n return hostPromiseWith(ctx, p, v => toGuest(ctx, v, opts), e => toGuest(ctx, e, opts));\n}\n\n/* hostPromise with the conversions supplied by the caller (the membrane\n converts results live); `reject` converts a rejection reason or an\n exception thrown by `resolve` */\nexport function hostPromiseWith(ctx: JSContext, p: PromiseLike<unknown>, resolve: (v: unknown) => JSValue,\n reject: (e: unknown) => JSValue): JSValue {\n const funcs: [JSValue, JSValue] = [undefined, undefined];\n const promise = JS_NewPromiseCapability(ctx, funcs);\n if (JS_IsException(promise)) throwGuestException(ctx);\n const settle = (ok: boolean, v: unknown) => {\n let fn = ok ? funcs[0] : funcs[1];\n let g: JSValue;\n try { g = ok ? resolve(v) : reject(v); } catch (e) { fn = funcs[1]; g = reject(e); }\n JS_Call(ctx, fn, undefined, [g]);\n drainJobs(ctx);\n };\n p.then(v => settle(true, v), e => settle(false, e));\n return promise;\n}\n\n/* define a global variable in the guest */\nexport function expose(ctx: JSContext, name: string, value: unknown, opts: ToGuestOptions = {}): void {\n if (JS_SetPropertyStr(ctx, ctx.global_obj, name, toGuest(ctx, value, opts)) < 0) throwGuestException(ctx);\n}\n\n/* guest value -> plain host value: objects and arrays are copied, guest\n functions become host functions (that call into the guest), guest\n promises become host promises, errors become host Errors */\nexport function fromGuest(ctx: JSContext, value: JSValue): unknown {\n return fromGuestRec(ctx, value, new Map(), undefined);\n}\n\n/* returned by a fromGuestWith hook to let the default conversion handle a value */\nexport const FROM_GUEST_DEFAULT: unique symbol = Symbol('fromGuest default');\nexport type FromGuestHook = (v: JSValue) => unknown;\n\n/* fromGuest with a hook that is offered every value first, at every depth\n (the membrane unwraps its proxies and wraps guest functions this way) */\nexport function fromGuestWith(ctx: JSContext, value: JSValue, hook: FromGuestHook): unknown {\n return fromGuestRec(ctx, value, new Map(), hook);\n}\n\nfunction fromGuestRec(ctx: JSContext, v: JSValue, seen: Map<object, unknown>, hook: FromGuestHook | undefined): unknown {\n if (hook !== undefined) {\n const r = hook(v);\n if (r !== FROM_GUEST_DEFAULT) return r;\n }\n if (typeof v === 'function') {\n return (...args: unknown[]) => {\n const r = JS_Call(ctx, v, undefined, args.map(a => toGuest(ctx, a)));\n if (JS_IsException(r)) throwGuestException(ctx);\n return fromGuest(ctx, r);\n };\n }\n if (typeof v !== 'object' || v === null) return v;\n const cached = seen.get(v);\n if (cached !== undefined) return cached;\n const o = v as any;\n switch (JS_GetClassID(v)) {\n case JSClassID.PROMISE:\n return guestPromiseToHost(ctx, v);\n case JSClassID.DATE:\n return new Date(JS_GetAnyOpaque(v) as number);\n case JSClassID.ERROR:\n return guestErrorToHost(ctx, v);\n case JSClassID.REGEXP:\n return new RegExp(o.source, o.flags);\n case JSClassID.MAP: {\n const m = new Map(); seen.set(v, m);\n for (const [k, val] of Map.prototype.entries.call(o)) m.set(fromGuestRec(ctx, k, seen, hook), fromGuestRec(ctx, val, seen, hook));\n return m;\n }\n case JSClassID.SET: {\n const s = new Set(); seen.set(v, s);\n for (const val of Set.prototype.values.call(o)) s.add(fromGuestRec(ctx, val, seen, hook));\n return s;\n }\n case JSClassID.ARRAY_BUFFER:\n /* the guest object is the host ArrayBuffer re-prototyped: copy it */\n return new Uint8Array(o as ArrayBuffer).slice().buffer;\n }\n if (ArrayBuffer.isView(o)) {\n /* guest typed arrays are host views re-prototyped: copy with the host constructor */\n const Ctor = (globalThis as any)[(o as any)[Symbol.toStringTag]];\n return Ctor ? new Ctor(o as any) : new Uint8Array(o as any);\n }\n if (Array.isArray(o)) {\n const a: unknown[] = []; seen.set(v, a);\n for (let i = 0; i < o.length; i++) a[i] = fromGuestRec(ctx, o[i], seen, hook);\n return a;\n }\n const r: Record<PropertyKey, unknown> = {}; seen.set(v, r);\n for (const k of Reflect.ownKeys(o)) {\n const d = Reflect.getOwnPropertyDescriptor(o, k)!;\n if (!d.enumerable) continue;\n r[k] = fromGuestRec(ctx, o[k], seen, hook);\n }\n return r;\n}\n\n/* a host promise that settles when the guest promise does */\nexport function guestPromiseToHost(ctx: JSContext, promise: JSValue): Promise<unknown> {\n return guestPromiseToHostWith(ctx, promise, v => fromGuest(ctx, v), e => fromGuestRejection(ctx, e));\n}\n\n/* guestPromiseToHost with the conversions supplied by the caller */\nexport function guestPromiseToHostWith(ctx: JSContext, promise: JSValue, convert: (v: JSValue) => unknown,\n convertRejection: (e: JSValue) => unknown): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const then = JS_GetPropertyStr(ctx, promise, 'then');\n const settle = (fn: (x: unknown) => void, conv: (v: JSValue) => unknown, v: JSValue): JSValue => {\n try { fn(conv(v)); } catch (e) { reject(e); }\n return undefined;\n };\n const onFul = JS_NewCFunction(ctx, (_c, _t, argv) => settle(resolve, convert, argv[0]), 'resolve', 1);\n const onRej = JS_NewCFunction(ctx, (_c, _t, argv) => settle(reject, convertRejection, argv[0]), 'reject', 1);\n const r = JS_Call(ctx, then, promise, [onFul, onRej]);\n if (JS_IsException(r)) reject(guestErrorToHost(ctx, JS_GetException(ctx)));\n drainJobs(ctx);\n });\n}\n\nfunction fromGuestRejection(ctx: JSContext, reason: JSValue): unknown {\n if (JS_IsObject(reason) && JS_GetClassID(reason) === JSClassID.ERROR) return guestErrorToHost(ctx, reason);\n return fromGuest(ctx, reason);\n}\n"]}
@@ -15,6 +15,8 @@ export { jit_config, jit_configure, jit_compile, jit_generate_source, jit_stats,
15
15
  export { JS_EvalInternal, next_token, JSParseState, TOK } from './parser.ts';
16
16
  export { toGuest, fromGuest, expose, hostFunction, hostPromise, guestPromiseToHost, guestErrorToHost, isGuestValue, drainJobs } from './embed.ts';
17
17
  export type { ToGuestOptions } from './embed.ts';
18
+ export { exposeLive, toGuestLive, isLiveProxy } from './membrane.ts';
19
+ export type { MembranePolicy } from './membrane.ts';
18
20
  import { JSContext, JSValue, JSRuntime } from './quickjs.ts';
19
21
  export declare function evalOrThrow(ctx: JSContext, src: string, filename?: string, flags?: number): JSValue;
20
22
  export declare function formatException(ctx: JSContext, exc: JSValue): string;
package/dist/jseption.js CHANGED
@@ -19,6 +19,7 @@ export { JS_CallInternal, js_closure } from "./interpreter.js";
19
19
  export { jit_config, jit_configure, jit_compile, jit_generate_source, jit_stats, jit_probe, jit_is_wrapper, jit_default_mode } from "./jit.js";
20
20
  export { JS_EvalInternal, next_token, JSParseState } from "./parser.js";
21
21
  export { toGuest, fromGuest, expose, hostFunction, hostPromise, guestPromiseToHost, guestErrorToHost, isGuestValue, drainJobs } from "./embed.js";
22
+ export { exposeLive, toGuestLive, isLiveProxy } from "./membrane.js";
22
23
  import { JS_Eval, JS_IsException, JS_GetException, JS_ToString, JS_GetPropertyStr, JS_IsError, JS_EVAL_TYPE_GLOBAL, JS_ExecutePendingJob, JS_IsJobPending } from "./quickjs.js";
23
24
  /* convenience helpers for tests and the CLI */
24
25
  /* evaluate 'src' and return the result or throw a host Error describing the JS exception */
@@ -1 +1 @@
1
- {"version":3,"file":"jseption.js","sourceRoot":"","sources":["../src/jseption.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * jseption: TypeScript port of QuickJS - public entry point\n *\n * Importing this module loads the interpreter, the compiler and the\n * builtin objects and re-exports the core API.\n */\nimport './interpreter.ts';\nimport './parser.ts';\nimport './builtins/index.ts';\nimport './jit.ts';\nimport './module.ts';\n\nexport * from './quickjs.ts';\nexport { OP, opcode_info } from './opcodes.ts';\nexport { JS_WriteObject, JS_ReadObject, JS_WRITE_OBJ_SOURCE } from './bytecode.ts';\nexport { JSEPTION_VERSION } from './version.ts';\nexport { JS_SetModuleLoader, JS_EvalModule, JS_ImportModule, JS_GetModuleNamespace, JS_DetectModule,\n js_default_module_resolve } from './module.ts';\nexport type { JSModuleLoader, JSModuleSource, JSModuleLoadResult, JSModuleSourceType } from './module.ts';\nexport { JS_PromiseState, JS_PromiseResult, JS_NewPromiseCapability } from './builtins/promise.ts';\nexport { JS_CallInternal, js_closure } from './interpreter.ts';\nexport { jit_config, jit_configure, jit_compile, jit_generate_source, jit_stats, jit_probe, jit_is_wrapper, jit_default_mode } from './jit.ts';\nexport { JS_EvalInternal, next_token, JSParseState, TOK } from './parser.ts';\nexport { toGuest, fromGuest, expose, hostFunction, hostPromise, guestPromiseToHost, guestErrorToHost, isGuestValue, drainJobs } from './embed.ts';\nexport type { ToGuestOptions } from './embed.ts';\n\nimport { JSContext, JSValue, JS_Eval, JS_IsException, JS_GetException, JS_ToString, JS_GetPropertyStr, JS_IsError,\n JS_EVAL_TYPE_GLOBAL, JSRuntime, JS_ExecutePendingJob, JS_IsJobPending } from './quickjs.ts';\n\n/* convenience helpers for tests and the CLI */\n\n/* evaluate 'src' and return the result or throw a host Error describing the JS exception */\nexport function evalOrThrow(ctx: JSContext, src: string, filename = '<eval>', flags: number = JS_EVAL_TYPE_GLOBAL): JSValue {\n const r = JS_Eval(ctx, src, filename, flags);\n if (JS_IsException(r)) {\n const exc = JS_GetException(ctx);\n throw new Error(formatException(ctx, exc));\n }\n return r;\n}\n\nexport function formatException(ctx: JSContext, exc: JSValue): string {\n let msg: string;\n const s = JS_ToString(ctx, exc);\n if (JS_IsException(s)) { JS_GetException(ctx); msg = '[exception]'; }\n else msg = s as string;\n if (JS_IsError(ctx, exc)) {\n const stack = JS_GetPropertyStr(ctx, exc, 'stack');\n if (typeof stack === 'string' && stack.length > 0) msg += '\\n' + stack;\n }\n return msg;\n}\n\n/* run all pending promise jobs; returns the number of jobs executed */\nexport function runPendingJobs(rt: JSRuntime): number {\n let n = 0;\n const pctx = { ctx: null as JSContext | null };\n while (JS_IsJobPending(rt)) {\n const r = JS_ExecutePendingJob(rt, pctx);\n if (r < 0) {\n /* the exception is left in the context */\n if (pctx.ctx) {\n const exc = JS_GetException(pctx.ctx);\n throw new Error('uncaught exception in job: ' + formatException(pctx.ctx, exc));\n }\n }\n n++;\n }\n return n;\n}\n"]}
1
+ {"version":3,"file":"jseption.js","sourceRoot":"","sources":["../src/jseption.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,kBAAkB,CAAC;AAC1B,OAAO,aAAa,CAAC;AACrB,OAAO,qBAAqB,CAAC;AAC7B,OAAO,UAAU,CAAC;AAClB,OAAO,aAAa,CAAC;AAErB,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAM,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EACjG,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC/I,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAO,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAElJ,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAsB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAC/G,mBAAmB,EAAa,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE9F,+CAA+C;AAE/C,4FAA4F;AAC5F,MAAM,UAAU,WAAW,CAAC,GAAc,EAAE,GAAW,EAAE,QAAQ,GAAG,QAAQ,EAAE,QAAgB,mBAAmB;IAC/G,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7C,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAc,EAAE,GAAY;IAC1D,IAAI,GAAW,CAAC;IAChB,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;QAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAAC,GAAG,GAAG,aAAa,CAAC;IAAC,CAAC;;QAChE,GAAG,GAAG,CAAW,CAAC;IACvB,IAAI,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,GAAG,IAAI,IAAI,GAAG,KAAK,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,cAAc,CAAC,EAAa;IAC1C,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,IAAI,GAAG,EAAE,GAAG,EAAE,IAAwB,EAAE,CAAC;IAC/C,OAAO,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,oBAAoB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,0CAA0C;YAC1C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtC,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC","sourcesContent":["/*\n * jseption: TypeScript port of QuickJS - public entry point\n *\n * Importing this module loads the interpreter, the compiler and the\n * builtin objects and re-exports the core API.\n */\nimport './interpreter.ts';\nimport './parser.ts';\nimport './builtins/index.ts';\nimport './jit.ts';\nimport './module.ts';\n\nexport * from './quickjs.ts';\nexport { OP, opcode_info } from './opcodes.ts';\nexport { JS_WriteObject, JS_ReadObject, JS_WRITE_OBJ_SOURCE } from './bytecode.ts';\nexport { JSEPTION_VERSION } from './version.ts';\nexport { JS_SetModuleLoader, JS_EvalModule, JS_ImportModule, JS_GetModuleNamespace, JS_DetectModule,\n js_default_module_resolve } from './module.ts';\nexport type { JSModuleLoader, JSModuleSource, JSModuleLoadResult, JSModuleSourceType } from './module.ts';\nexport { JS_PromiseState, JS_PromiseResult, JS_NewPromiseCapability } from './builtins/promise.ts';\nexport { JS_CallInternal, js_closure } from './interpreter.ts';\nexport { jit_config, jit_configure, jit_compile, jit_generate_source, jit_stats, jit_probe, jit_is_wrapper, jit_default_mode } from './jit.ts';\nexport { JS_EvalInternal, next_token, JSParseState, TOK } from './parser.ts';\nexport { toGuest, fromGuest, expose, hostFunction, hostPromise, guestPromiseToHost, guestErrorToHost, isGuestValue, drainJobs } from './embed.ts';\nexport type { ToGuestOptions } from './embed.ts';\nexport { exposeLive, toGuestLive, isLiveProxy } from './membrane.ts';\nexport type { MembranePolicy } from './membrane.ts';\n\nimport { JSContext, JSValue, JS_Eval, JS_IsException, JS_GetException, JS_ToString, JS_GetPropertyStr, JS_IsError,\n JS_EVAL_TYPE_GLOBAL, JSRuntime, JS_ExecutePendingJob, JS_IsJobPending } from './quickjs.ts';\n\n/* convenience helpers for tests and the CLI */\n\n/* evaluate 'src' and return the result or throw a host Error describing the JS exception */\nexport function evalOrThrow(ctx: JSContext, src: string, filename = '<eval>', flags: number = JS_EVAL_TYPE_GLOBAL): JSValue {\n const r = JS_Eval(ctx, src, filename, flags);\n if (JS_IsException(r)) {\n const exc = JS_GetException(ctx);\n throw new Error(formatException(ctx, exc));\n }\n return r;\n}\n\nexport function formatException(ctx: JSContext, exc: JSValue): string {\n let msg: string;\n const s = JS_ToString(ctx, exc);\n if (JS_IsException(s)) { JS_GetException(ctx); msg = '[exception]'; }\n else msg = s as string;\n if (JS_IsError(ctx, exc)) {\n const stack = JS_GetPropertyStr(ctx, exc, 'stack');\n if (typeof stack === 'string' && stack.length > 0) msg += '\\n' + stack;\n }\n return msg;\n}\n\n/* run all pending promise jobs; returns the number of jobs executed */\nexport function runPendingJobs(rt: JSRuntime): number {\n let n = 0;\n const pctx = { ctx: null as JSContext | null };\n while (JS_IsJobPending(rt)) {\n const r = JS_ExecutePendingJob(rt, pctx);\n if (r < 0) {\n /* the exception is left in the context */\n if (pctx.ctx) {\n const exc = JS_GetException(pctx.ctx);\n throw new Error('uncaught exception in job: ' + formatException(pctx.ctx, exc));\n }\n }\n n++;\n }\n return n;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { JSContext, JSValue } from './quickjs.ts';
2
+ export interface MembranePolicy {
3
+ /** called for every key-based operation (read, `in`, own keys, descriptors,
4
+ * writes) on the host object `target`; any result but `true` hides the key */
5
+ allow?(target: object, key: PropertyKey): boolean;
6
+ /** let the guest set, define and delete properties on host objects
7
+ * (default false: read-only) */
8
+ writable?: boolean;
9
+ }
10
+ /** the guest view of a host value: primitives as is, host objects and
11
+ * functions as live membrane proxies (see docs/MEMBRANE.md) */
12
+ export declare function toGuestLive(ctx: JSContext, value: unknown, policy?: MembranePolicy): JSValue;
13
+ /** define the global `name` in the guest as a live view of `root` */
14
+ export declare function exposeLive(ctx: JSContext, name: string, root: unknown, policy?: MembranePolicy): void;
15
+ /** true if `value` is a membrane proxy */
16
+ export declare function isLiveProxy(value: unknown): boolean;
@@ -0,0 +1,576 @@
1
+ /* The membrane: live host objects for the guest.
2
+ *
3
+ * `toGuest`/`expose` (src/embed.ts) copy plain data and wrap functions; a
4
+ * host class instance is refused. The membrane instead hands the guest a
5
+ * live view of a host object graph: every host object or function the guest
6
+ * reaches from a root crosses as a host `Proxy` whose handler lives here.
7
+ * Each trap forwards the operation to the host object and converts what
8
+ * comes back the same way, so nested objects, method results and
9
+ * constructed instances are proxied lazily.
10
+ *
11
+ * A membrane proxy is not a guest Proxy (src/builtins/proxy.ts): the guest
12
+ * Proxy calls guest handler code, while this handler is host code that must
13
+ * never return a host value. The proxy's target is a private dummy (an empty
14
+ * null-prototype object, or an empty function for callables) so the host
15
+ * Proxy invariants never force a host value out, and the proxy has no engine
16
+ * metadata, so the engine treats it as an ordinary object or host function
17
+ * (`Reflect.get`, `Reflect.apply`, ... on it run the traps).
18
+ *
19
+ * The sandbox rules (always on; a policy can only narrow them):
20
+ * 1. host intrinsics (Function and its async/generator variants, eval,
21
+ * globalThis, Reflect, Proxy, Object, the Error constructors, the
22
+ * intrinsic prototypes, the methods of Object, Reflect, Object.prototype
23
+ * and Function.prototype) are never wrapped: they read as undefined, or
24
+ * raise a guest TypeError where a value is required;
25
+ * 2. constructor, prototype, __proto__, caller, callee, arguments and the
26
+ * legacy __define/lookup{G,S}etter__ read as undefined; the prototype of
27
+ * a proxy is the guest Object.prototype (Function.prototype for
28
+ * callables); writes are refused unless the policy is writable, and
29
+ * setPrototypeOf / preventExtensions are always refused;
30
+ * 3. lookups stop at the host Object.prototype / Function.prototype and
31
+ * continue on the guest's own, so call/apply/bind/toString/hasOwnProperty
32
+ * are the guest intrinsics operating on the proxy, never host methods;
33
+ * 4. getters run on the host, their results are converted like any value;
34
+ * 5. only the well-known symbols iterator, asyncIterator, toStringTag and
35
+ * toPrimitive (and hasInstance, answered by the membrane) are forwarded;
36
+ * host symbols are neither listed nor returned;
37
+ * 6. `policy.allow(target, key)` filters every key-based operation.
38
+ *
39
+ * See docs/MEMBRANE.md. */
40
+ import { JS_IsException, JS_GetException, JS_NewCFunction, JS_Call, JS_Throw, JS_NewArrayFrom, JS_NewErrorNative, JS_SetPropertyStr, JS_GetClassID, js_meta, } from "./quickjs.js";
41
+ import { toGuest, drainJobs, guestErrorToHost, hostPromiseWith, guestPromiseToHostWith, fromGuestWith, FROM_GUEST_DEFAULT, } from "./embed.js";
42
+ import { JS_NewDate } from "./builtins/date.js";
43
+ /* ------------------------------------------------------------------ */
44
+ /* host intrinsics, collected once at module load */
45
+ const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
46
+ const GeneratorFunction = Object.getPrototypeOf(function* () { }).constructor;
47
+ const AsyncGeneratorFunction = Object.getPrototypeOf(async function* () { }).constructor;
48
+ /* never wrapped, never returned to the guest */
49
+ const FORBIDDEN = new Set();
50
+ /* the host prototype walk stops here and continues on the guest prototype */
51
+ const WALK_STOP = new Set([Object.prototype, Function.prototype, globalThis]);
52
+ function forbid(v) {
53
+ if ((typeof v === 'object' && v !== null) || typeof v === 'function')
54
+ FORBIDDEN.add(v);
55
+ }
56
+ /* the functions stored on an object (values and accessors) */
57
+ function forbidMembers(o) {
58
+ for (const k of Reflect.ownKeys(o)) {
59
+ const d = Reflect.getOwnPropertyDescriptor(o, k);
60
+ if (!d)
61
+ continue;
62
+ if (typeof d.value === 'function')
63
+ forbid(d.value);
64
+ forbid(d.get);
65
+ forbid(d.set);
66
+ }
67
+ }
68
+ (function collectIntrinsics() {
69
+ const g = globalThis;
70
+ for (const v of [Function, AsyncFunction, GeneratorFunction, AsyncGeneratorFunction, eval, globalThis, Reflect, Proxy, Object])
71
+ forbid(v);
72
+ /* the host error constructors expose stack-trace hooks (captureStackTrace,
73
+ prepareStackTrace) that can hand out host frames */
74
+ for (const name of ['Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
75
+ 'AggregateError', 'SuppressedError'])
76
+ forbid(g[name]);
77
+ /* the prototype of every standard constructor */
78
+ const ctors = ['Object', 'Function', 'Array', 'String', 'Number', 'Boolean', 'Symbol', 'BigInt', 'Error', 'EvalError',
79
+ 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'AggregateError', 'SuppressedError', 'Date',
80
+ 'RegExp', 'Map', 'Set', 'WeakMap', 'WeakSet', 'WeakRef', 'FinalizationRegistry', 'Promise', 'ArrayBuffer',
81
+ 'SharedArrayBuffer', 'DataView', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array',
82
+ 'Int32Array', 'Uint32Array', 'Float16Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array',
83
+ 'Iterator', 'AsyncIterator', 'DisposableStack', 'AsyncDisposableStack'];
84
+ for (const name of ctors) {
85
+ const c = g[name];
86
+ if (typeof c === 'function')
87
+ forbid(c.prototype);
88
+ }
89
+ const TypedArray = Object.getPrototypeOf(Int8Array);
90
+ forbid(TypedArray);
91
+ forbid(TypedArray.prototype);
92
+ for (const F of [AsyncFunction, GeneratorFunction, AsyncGeneratorFunction]) {
93
+ forbid(F.prototype); /* %AsyncFunction.prototype%, %GeneratorFunction.prototype%, ... */
94
+ forbid(F.prototype.prototype); /* %GeneratorPrototype%, %AsyncGeneratorPrototype% */
95
+ }
96
+ const arrayIter = Object.getPrototypeOf([][Symbol.iterator]());
97
+ forbid(arrayIter);
98
+ forbid(Object.getPrototypeOf(arrayIter)); /* %IteratorPrototype% */
99
+ forbid(Object.getPrototypeOf(Object.getPrototypeOf((async function* () { })()))); /* %AsyncGeneratorPrototype% */
100
+ forbid(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf((async function* () { })())))); /* %AsyncIteratorPrototype% */
101
+ forbid(Object.getPrototypeOf(new Map().entries()));
102
+ forbid(Object.getPrototypeOf(new Set().values()));
103
+ forbid(Object.getPrototypeOf(''[Symbol.iterator]()));
104
+ forbid(Object.getPrototypeOf(/a/[Symbol.matchAll]('a')));
105
+ /* %ThrowTypeError% and the methods that reach code, prototypes or properties
106
+ of arbitrary objects */
107
+ forbid(Reflect.getOwnPropertyDescriptor(Function.prototype, 'caller')?.get);
108
+ for (const o of [Object, Reflect, Proxy, Object.prototype, Function.prototype])
109
+ forbidMembers(o);
110
+ })();
111
+ const BLOCKED_KEYS = new Set([
112
+ 'constructor', 'prototype', '__proto__', 'caller', 'callee', 'arguments',
113
+ '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__',
114
+ ]);
115
+ const WELL_KNOWN_SYMBOLS = new Set(Reflect.ownKeys(Symbol).map(k => Symbol[k])
116
+ .filter((v) => typeof v === 'symbol'));
117
+ /* the well-known symbols forwarded as keys */
118
+ const FORWARDED_SYMBOLS = new Set([Symbol.iterator, Symbol.asyncIterator, Symbol.toStringTag, Symbol.toPrimitive]);
119
+ const ERROR_KINDS = [
120
+ [TypeError, 4 /* JSErrorEnum.TYPE_ERROR */], [RangeError, 1 /* JSErrorEnum.RANGE_ERROR */], [SyntaxError, 3 /* JSErrorEnum.SYNTAX_ERROR */],
121
+ [ReferenceError, 2 /* JSErrorEnum.REFERENCE_ERROR */], [URIError, 5 /* JSErrorEnum.URI_ERROR */], [EvalError, 0 /* JSErrorEnum.EVAL_ERROR */],
122
+ ];
123
+ const STANDARD_ERROR_NAMES = new Set(['Error', 'TypeError', 'RangeError', 'SyntaxError', 'ReferenceError', 'URIError', 'EvalError']);
124
+ function isHostConstructor(f) {
125
+ try {
126
+ Reflect.construct(String, [], f);
127
+ return true;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
133
+ function isObjectLike(v) {
134
+ return (typeof v === 'object' && v !== null) || typeof v === 'function';
135
+ }
136
+ /* ------------------------------------------------------------------ */
137
+ /* registries shared by every membrane */
138
+ /* membrane proxy -> the host object it stands for */
139
+ const proxyHost = new WeakMap();
140
+ /* host callable made for a guest function -> that guest function */
141
+ const callableGuest = new WeakMap();
142
+ /* host Error thrown to host code for a guest exception -> the guest exception */
143
+ const thrownGuest = new WeakMap();
144
+ /* one membrane per context and policy */
145
+ const membranes = new WeakMap();
146
+ /* membrane traps running now, per runtime. Compiled guest code pushes no interpreter frame, so
147
+ when it calls into host code through a proxy, `rt.current_stack_frame` is null although guest
148
+ code is on the stack; this count is what tells a guest callback the host calls back that it is
149
+ not the outermost call */
150
+ const trapDepth = new WeakMap();
151
+ function membraneFor(ctx, policy) {
152
+ let e = membranes.get(ctx);
153
+ if (!e) {
154
+ e = { byPolicy: new WeakMap() };
155
+ membranes.set(ctx, e);
156
+ }
157
+ if (policy === undefined)
158
+ return (e.plain ??= new Membrane(ctx, {}));
159
+ let m = e.byPolicy.get(policy);
160
+ if (!m) {
161
+ m = new Membrane(ctx, policy);
162
+ e.byPolicy.set(policy, m);
163
+ }
164
+ return m;
165
+ }
166
+ /* ------------------------------------------------------------------ */
167
+ class Membrane {
168
+ ctx;
169
+ proxies = new WeakMap(); /* host object -> proxy */
170
+ callables = new WeakMap(); /* guest function -> host callable */
171
+ hasInstanceFns = new WeakMap();
172
+ guestSymbols = new WeakSet(); /* symbols the guest handed to the host */
173
+ writable;
174
+ allowFn;
175
+ constructor(ctx, policy) {
176
+ this.ctx = ctx;
177
+ this.writable = policy.writable === true;
178
+ this.allowFn = typeof policy.allow === 'function' ? policy.allow.bind(policy) : undefined;
179
+ }
180
+ /* ---------------- host -> guest ---------------- */
181
+ toGuest(v, seen) {
182
+ switch (typeof v) {
183
+ case 'undefined':
184
+ case 'boolean':
185
+ case 'number':
186
+ case 'string':
187
+ case 'bigint':
188
+ return v;
189
+ case 'symbol':
190
+ return this.symbolCrosses(v) ? v : undefined;
191
+ }
192
+ if (v === null)
193
+ return null;
194
+ const o = v;
195
+ if (FORBIDDEN.has(o))
196
+ return undefined;
197
+ const p = proxyHost.get(o);
198
+ if (p !== undefined)
199
+ return p.membrane.ctx === this.ctx ? o : this.toGuest(p.host, seen);
200
+ if (typeof o === 'function') {
201
+ const g = callableGuest.get(o);
202
+ if (g !== undefined)
203
+ return g;
204
+ }
205
+ if (this.isGuestOwned(o))
206
+ return o;
207
+ if (o instanceof Promise) {
208
+ return hostPromiseWith(this.ctx, o, r => this.toGuest(r), e => this.thrownToGuest(e));
209
+ }
210
+ if (Array.isArray(o)) {
211
+ /* arrays are snapshots: a fresh guest array whose elements are converted */
212
+ seen ??= new Map();
213
+ const cached = seen.get(o);
214
+ if (cached !== undefined)
215
+ return cached;
216
+ const arr = JS_NewArrayFrom(this.ctx, []);
217
+ seen.set(o, arr);
218
+ const len = o.length;
219
+ for (let i = 0; i < len; i++)
220
+ arr[i] = this.toGuest(o[i], seen);
221
+ return arr;
222
+ }
223
+ if (o instanceof Date)
224
+ return JS_NewDate(this.ctx, Date.prototype.getTime.call(o));
225
+ if (o instanceof Error)
226
+ return this.errorToGuest(o);
227
+ if (o instanceof RegExp || o instanceof ArrayBuffer || ArrayBuffer.isView(o))
228
+ return toGuest(this.ctx, o);
229
+ return this.wrap(o);
230
+ }
231
+ /* a well-known or registered symbol, or one the guest gave to the host */
232
+ symbolCrosses(s) {
233
+ return WELL_KNOWN_SYMBOLS.has(s) || Symbol.keyFor(s) !== undefined || this.guestSymbols.has(s);
234
+ }
235
+ /* an engine object, or an object whose prototype chain reaches this
236
+ context's guest Object.prototype / Function.prototype */
237
+ isGuestOwned(o) {
238
+ if (js_meta.has(o))
239
+ return true;
240
+ try {
241
+ return this.chainReachesGuest(o);
242
+ }
243
+ catch {
244
+ return false; /* a host proxy whose getPrototypeOf throws */
245
+ }
246
+ }
247
+ chainReachesGuest(o) {
248
+ const ctx = this.ctx;
249
+ const op = ctx.class_proto[1 /* JSClassID.OBJECT */], fp = ctx.function_proto;
250
+ let p = Reflect.getPrototypeOf(o);
251
+ for (let i = 0; i < 64 && p !== null; i++) {
252
+ if (p === op || p === fp)
253
+ return true;
254
+ if (WALK_STOP.has(p) || FORBIDDEN.has(p) || proxyHost.has(p))
255
+ return false;
256
+ p = Reflect.getPrototypeOf(p);
257
+ }
258
+ return false;
259
+ }
260
+ errorToGuest(e) {
261
+ let kind = 8 /* JSErrorEnum.PLAIN_ERROR */;
262
+ for (const [C, k] of ERROR_KINDS)
263
+ if (e instanceof C) {
264
+ kind = k;
265
+ break;
266
+ }
267
+ let message = '', name;
268
+ try {
269
+ const m = e.message;
270
+ message = typeof m === 'string' ? m : '';
271
+ name = e.name;
272
+ }
273
+ catch { /* hostile getter */ }
274
+ const g = JS_NewErrorNative(this.ctx, kind, message);
275
+ if (kind === 8 /* JSErrorEnum.PLAIN_ERROR */ && typeof name === 'string' && !STANDARD_ERROR_NAMES.has(name)) {
276
+ Reflect.defineProperty(g, 'name', { value: name, writable: true, enumerable: false, configurable: true });
277
+ }
278
+ return g;
279
+ }
280
+ /* convert anything the host threw into a value to throw in the guest; the
281
+ host exception object itself never crosses */
282
+ thrownToGuest(e) {
283
+ if (isObjectLike(e)) {
284
+ const g = thrownGuest.get(e);
285
+ if (g !== undefined)
286
+ return g; /* a guest exception that passed through host code */
287
+ if (proxyHost.has(e) || this.isGuestOwned(e))
288
+ return e; /* thrown by guest code */
289
+ if (e instanceof Error)
290
+ return this.errorToGuest(e);
291
+ let message = 'host exception';
292
+ try {
293
+ const m = e.message;
294
+ if (typeof m === 'string')
295
+ message = m;
296
+ }
297
+ catch { /* hostile getter */ }
298
+ return JS_NewErrorNative(this.ctx, 8 /* JSErrorEnum.PLAIN_ERROR */, message);
299
+ }
300
+ if (typeof e === 'symbol')
301
+ return this.symbolCrosses(e) ? e : undefined;
302
+ return e;
303
+ }
304
+ guestTypeError(message) {
305
+ return JS_NewErrorNative(this.ctx, 4 /* JSErrorEnum.TYPE_ERROR */, message);
306
+ }
307
+ /* the proxy for a host object (one per host object) */
308
+ wrap(host) {
309
+ const cached = this.proxies.get(host);
310
+ if (cached !== undefined)
311
+ return cached;
312
+ let target;
313
+ const callable = typeof host === 'function';
314
+ if (callable) {
315
+ /* constructible or not like the host function; no own properties, so
316
+ no target invariant constrains the traps */
317
+ const f = isHostConstructor(host) ? Function.prototype.bind.call(function () { }, null) : () => { };
318
+ Reflect.deleteProperty(f, 'name');
319
+ Reflect.deleteProperty(f, 'length');
320
+ Reflect.setPrototypeOf(f, null);
321
+ target = f;
322
+ }
323
+ else {
324
+ target = Object.create(null);
325
+ }
326
+ const proxy = new Proxy(target, this.handler(host, callable));
327
+ this.proxies.set(host, proxy);
328
+ proxyHost.set(proxy, { host, membrane: this });
329
+ return proxy;
330
+ }
331
+ keyAllowed(host, key) {
332
+ if (typeof key === 'symbol') {
333
+ if (WELL_KNOWN_SYMBOLS.has(key) && !FORWARDED_SYMBOLS.has(key))
334
+ return false;
335
+ }
336
+ else if (BLOCKED_KEYS.has(key)) {
337
+ return false;
338
+ }
339
+ return this.allowFn === undefined || this.allowFn(host, key) === true;
340
+ }
341
+ /* listed by ownKeys: host symbols other than the forwarded well-known ones stay hidden */
342
+ keyListed(host, key) {
343
+ if (typeof key === 'symbol' && !FORWARDED_SYMBOLS.has(key) && !this.guestSymbols.has(key))
344
+ return false;
345
+ return this.keyAllowed(host, key);
346
+ }
347
+ /* walk the host prototype chain up to (not including) the host
348
+ Object.prototype / Function.prototype */
349
+ lookup(host, key) {
350
+ let o = host;
351
+ for (let depth = 0; o !== null && depth < 10000; depth++) {
352
+ if (WALK_STOP.has(o))
353
+ return undefined;
354
+ const d = Reflect.getOwnPropertyDescriptor(o, key);
355
+ if (d !== undefined)
356
+ return d;
357
+ o = Reflect.getPrototypeOf(o);
358
+ }
359
+ return undefined;
360
+ }
361
+ hostOf(v, fallback) {
362
+ return isObjectLike(v) ? proxyHost.get(v)?.host ?? fallback : fallback;
363
+ }
364
+ hasInstance(host) {
365
+ let f = this.hasInstanceFns.get(host);
366
+ if (f === undefined) {
367
+ f = JS_NewCFunction(this.ctx, (ctx, _this, argv) => {
368
+ const v = argv[0];
369
+ const h = isObjectLike(v) ? proxyHost.get(v)?.host : undefined;
370
+ if (h === undefined)
371
+ return false;
372
+ try {
373
+ return h instanceof host;
374
+ }
375
+ catch (e) {
376
+ return JS_Throw(ctx, this.thrownToGuest(e));
377
+ }
378
+ }, '[Symbol.hasInstance]', 1);
379
+ this.hasInstanceFns.set(host, f);
380
+ }
381
+ return f;
382
+ }
383
+ handler(host, callable) {
384
+ const m = this;
385
+ const ctx = this.ctx;
386
+ const guestProto = () => (callable ? ctx.function_proto : ctx.class_proto[1 /* JSClassID.OBJECT */]);
387
+ /* every trap converts what the host throws, and counts as guest code on the stack while it
388
+ runs host code */
389
+ const rt = ctx.rt;
390
+ const guard = (fn) => (...args) => {
391
+ trapDepth.set(rt, (trapDepth.get(rt) ?? 0) + 1);
392
+ try {
393
+ return fn(...args);
394
+ }
395
+ catch (e) {
396
+ throw m.thrownToGuest(e);
397
+ }
398
+ finally {
399
+ trapDepth.set(rt, trapDepth.get(rt) - 1);
400
+ }
401
+ };
402
+ const refuse = (what, key) => {
403
+ const k = key === undefined ? '' : ` '${typeof key === 'symbol' ? key.description ?? 'symbol' : key}'`;
404
+ throw m.guestTypeError(`cannot ${what}${k}: host object is read-only`);
405
+ };
406
+ const proxyOf = () => m.proxies.get(host);
407
+ return {
408
+ get: guard((_t, key, receiver) => {
409
+ if (callable && key === Symbol.hasInstance)
410
+ return m.hasInstance(host);
411
+ if (!m.keyAllowed(host, key))
412
+ return undefined;
413
+ const d = m.lookup(host, key);
414
+ if (d === undefined)
415
+ return Reflect.get(guestProto(), key, receiver);
416
+ if ('value' in d)
417
+ return m.toGuest(d.value);
418
+ if (d.get === undefined)
419
+ return undefined;
420
+ return m.toGuest(Reflect.apply(d.get, m.hostOf(receiver, host), []));
421
+ }),
422
+ has: guard((_t, key) => {
423
+ if (callable && key === Symbol.hasInstance)
424
+ return true;
425
+ if (!m.keyAllowed(host, key))
426
+ return false;
427
+ if (m.lookup(host, key) !== undefined)
428
+ return true;
429
+ return Reflect.has(guestProto(), key);
430
+ }),
431
+ ownKeys: guard((_t) => Reflect.ownKeys(host).filter(k => m.keyListed(host, k))),
432
+ getOwnPropertyDescriptor: guard((_t, key) => {
433
+ if (!m.keyAllowed(host, key))
434
+ return undefined;
435
+ const d = Reflect.getOwnPropertyDescriptor(host, key);
436
+ if (d === undefined)
437
+ return undefined;
438
+ if ('value' in d) {
439
+ return { value: m.toGuest(d.value), writable: m.writable && d.writable === true, enumerable: d.enumerable === true, configurable: true };
440
+ }
441
+ return {
442
+ get: d.get === undefined ? undefined : m.toGuest(d.get),
443
+ set: d.set === undefined || !m.writable ? undefined : m.toGuest(d.set),
444
+ enumerable: d.enumerable === true, configurable: true,
445
+ };
446
+ }),
447
+ set: guard((_t, key, value, receiver) => {
448
+ if (receiver !== proxyOf() && !(isObjectLike(receiver) && proxyHost.has(receiver))) {
449
+ /* a guest object inheriting from the proxy: the property lands on it */
450
+ return Reflect.defineProperty(receiver, key, { value, writable: true, enumerable: true, configurable: true });
451
+ }
452
+ if (!m.writable || !m.keyAllowed(host, key))
453
+ refuse('assign to property', key);
454
+ return Reflect.set(host, key, m.fromGuest(value), m.hostOf(receiver, host));
455
+ }),
456
+ defineProperty: guard((_t, key, desc) => {
457
+ if (!m.writable || !m.keyAllowed(host, key))
458
+ refuse('define property', key);
459
+ if (desc.configurable === false)
460
+ throw m.guestTypeError('cannot define a non-configurable property on a host object');
461
+ const hd = {};
462
+ if ('value' in desc)
463
+ hd.value = m.fromGuest(desc.value);
464
+ if ('get' in desc)
465
+ hd.get = m.fromGuest(desc.get);
466
+ if ('set' in desc)
467
+ hd.set = m.fromGuest(desc.set);
468
+ if ('writable' in desc)
469
+ hd.writable = desc.writable;
470
+ if ('enumerable' in desc)
471
+ hd.enumerable = desc.enumerable;
472
+ hd.configurable = true;
473
+ return Reflect.defineProperty(host, key, hd);
474
+ }),
475
+ deleteProperty: guard((_t, key) => {
476
+ if (!m.writable || !m.keyAllowed(host, key))
477
+ refuse('delete property', key);
478
+ return Reflect.deleteProperty(host, key);
479
+ }),
480
+ getPrototypeOf: () => guestProto(),
481
+ setPrototypeOf: () => false,
482
+ isExtensible: () => true,
483
+ preventExtensions: () => false,
484
+ apply: guard((_t, thisArg, args) => {
485
+ const hostThis = thisArg === ctx.global_obj ? undefined : m.fromGuest(thisArg);
486
+ const hostArgs = args.map(a => m.fromGuest(a));
487
+ return m.toGuest(Reflect.apply(host, hostThis, hostArgs));
488
+ }),
489
+ construct: guard((_t, args, newTarget) => {
490
+ if (newTarget !== proxyOf())
491
+ throw m.guestTypeError('host constructors cannot be subclassed from the guest');
492
+ const r = m.toGuest(Reflect.construct(host, args.map(a => m.fromGuest(a))));
493
+ if (!isObjectLike(r))
494
+ throw m.guestTypeError('host constructor returned a value that cannot cross the membrane');
495
+ return r;
496
+ }),
497
+ };
498
+ }
499
+ /* ---------------- guest -> host ---------------- */
500
+ fromGuest(v) {
501
+ return fromGuestWith(this.ctx, v, x => this.fromGuestHook(x));
502
+ }
503
+ fromGuestHook(v) {
504
+ if (typeof v === 'symbol') {
505
+ if (!WELL_KNOWN_SYMBOLS.has(v) && Symbol.keyFor(v) === undefined)
506
+ this.guestSymbols.add(v);
507
+ return v;
508
+ }
509
+ if (!isObjectLike(v))
510
+ return FROM_GUEST_DEFAULT;
511
+ const p = proxyHost.get(v);
512
+ if (p !== undefined)
513
+ return p.host;
514
+ if (typeof v === 'function')
515
+ return this.callable(v);
516
+ if (JS_GetClassID(v) === 45 /* JSClassID.PROMISE */) {
517
+ return guestPromiseToHostWith(this.ctx, v, x => this.fromGuest(x), e => (JS_GetClassID(e) === 3 /* JSClassID.ERROR */ ? guestErrorToHost(this.ctx, e) : this.fromGuest(e)));
518
+ }
519
+ return FROM_GUEST_DEFAULT;
520
+ }
521
+ /* a host function that runs the guest function (one per guest function) */
522
+ callable(fn) {
523
+ const cached = this.callables.get(fn);
524
+ if (cached !== undefined)
525
+ return cached;
526
+ const m = this;
527
+ const ctx = this.ctx;
528
+ const c = {
529
+ guestCallback(...args) {
530
+ /* outermost: no guest code below this call, neither an interpreter frame nor a membrane
531
+ trap (the way compiled guest code reaches host code) */
532
+ const outermost = ctx.rt.current_stack_frame === null && (trapDepth.get(ctx.rt) ?? 0) === 0;
533
+ try {
534
+ const r = JS_Call(ctx, fn, m.toGuest(this), args.map(a => m.toGuest(a)));
535
+ if (JS_IsException(r)) {
536
+ const exc = JS_GetException(ctx);
537
+ const he = guestErrorToHost(ctx, exc);
538
+ thrownGuest.set(he, exc);
539
+ throw he;
540
+ }
541
+ return m.fromGuest(r);
542
+ }
543
+ finally {
544
+ /* called from host code outside any guest call (an event, a timer, a
545
+ promise reaction): run the guest jobs the callback queued */
546
+ if (outermost)
547
+ drainJobs(ctx);
548
+ }
549
+ },
550
+ }.guestCallback;
551
+ this.callables.set(fn, c);
552
+ callableGuest.set(c, fn);
553
+ return c;
554
+ }
555
+ }
556
+ /* ------------------------------------------------------------------ */
557
+ /* public API */
558
+ /** the guest view of a host value: primitives as is, host objects and
559
+ * functions as live membrane proxies (see docs/MEMBRANE.md) */
560
+ export function toGuestLive(ctx, value, policy) {
561
+ if (FORBIDDEN.has(value))
562
+ throw new TypeError('toGuestLive: refusing to hand a host intrinsic to the guest');
563
+ return membraneFor(ctx, policy).toGuest(value);
564
+ }
565
+ /** define the global `name` in the guest as a live view of `root` */
566
+ export function exposeLive(ctx, name, root, policy) {
567
+ const g = toGuestLive(ctx, root, policy);
568
+ if (JS_SetPropertyStr(ctx, ctx.global_obj, name, g) < 0) {
569
+ throw guestErrorToHost(ctx, JS_GetException(ctx));
570
+ }
571
+ }
572
+ /** true if `value` is a membrane proxy */
573
+ export function isLiveProxy(value) {
574
+ return isObjectLike(value) && proxyHost.has(value);
575
+ }
576
+ //# sourceMappingURL=membrane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membrane.js","sourceRoot":"","sources":["../src/membrane.ts"],"names":[],"mappings":"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","sourcesContent":["/* The membrane: live host objects for the guest.\n *\n * `toGuest`/`expose` (src/embed.ts) copy plain data and wrap functions; a\n * host class instance is refused. The membrane instead hands the guest a\n * live view of a host object graph: every host object or function the guest\n * reaches from a root crosses as a host `Proxy` whose handler lives here.\n * Each trap forwards the operation to the host object and converts what\n * comes back the same way, so nested objects, method results and\n * constructed instances are proxied lazily.\n *\n * A membrane proxy is not a guest Proxy (src/builtins/proxy.ts): the guest\n * Proxy calls guest handler code, while this handler is host code that must\n * never return a host value. The proxy's target is a private dummy (an empty\n * null-prototype object, or an empty function for callables) so the host\n * Proxy invariants never force a host value out, and the proxy has no engine\n * metadata, so the engine treats it as an ordinary object or host function\n * (`Reflect.get`, `Reflect.apply`, ... on it run the traps).\n *\n * The sandbox rules (always on; a policy can only narrow them):\n * 1. host intrinsics (Function and its async/generator variants, eval,\n * globalThis, Reflect, Proxy, Object, the Error constructors, the\n * intrinsic prototypes, the methods of Object, Reflect, Object.prototype\n * and Function.prototype) are never wrapped: they read as undefined, or\n * raise a guest TypeError where a value is required;\n * 2. constructor, prototype, __proto__, caller, callee, arguments and the\n * legacy __define/lookup{G,S}etter__ read as undefined; the prototype of\n * a proxy is the guest Object.prototype (Function.prototype for\n * callables); writes are refused unless the policy is writable, and\n * setPrototypeOf / preventExtensions are always refused;\n * 3. lookups stop at the host Object.prototype / Function.prototype and\n * continue on the guest's own, so call/apply/bind/toString/hasOwnProperty\n * are the guest intrinsics operating on the proxy, never host methods;\n * 4. getters run on the host, their results are converted like any value;\n * 5. only the well-known symbols iterator, asyncIterator, toStringTag and\n * toPrimitive (and hasInstance, answered by the membrane) are forwarded;\n * host symbols are neither listed nor returned;\n * 6. `policy.allow(target, key)` filters every key-based operation.\n *\n * See docs/MEMBRANE.md. */\n\nimport {\n JSContext, JSValue, JSClassID, JS_IsException, JS_GetException, JS_NewCFunction, JS_Call, JS_Throw,\n JS_NewArrayFrom, JS_NewErrorNative, JS_SetPropertyStr, JS_GetClassID, js_meta,\n} from './quickjs.ts';\nimport { JSErrorEnum } from './values.ts';\nimport {\n toGuest, drainJobs, guestErrorToHost, hostPromiseWith, guestPromiseToHostWith, fromGuestWith, FROM_GUEST_DEFAULT,\n} from './embed.ts';\nimport { JS_NewDate } from './builtins/date.ts';\n\nexport interface MembranePolicy {\n /** called for every key-based operation (read, `in`, own keys, descriptors,\n * writes) on the host object `target`; any result but `true` hides the key */\n allow?(target: object, key: PropertyKey): boolean;\n /** let the guest set, define and delete properties on host objects\n * (default false: read-only) */\n writable?: boolean;\n}\n\n/* ------------------------------------------------------------------ */\n/* host intrinsics, collected once at module load */\n\nconst AsyncFunction = Object.getPrototypeOf(async function () {}).constructor as Function;\nconst GeneratorFunction = Object.getPrototypeOf(function* () {}).constructor as Function;\nconst AsyncGeneratorFunction = Object.getPrototypeOf(async function* () {}).constructor as Function;\n\n/* never wrapped, never returned to the guest */\nconst FORBIDDEN = new Set<unknown>();\n/* the host prototype walk stops here and continues on the guest prototype */\nconst WALK_STOP = new Set<unknown>([Object.prototype, Function.prototype, globalThis]);\n\nfunction forbid(v: unknown): void {\n if ((typeof v === 'object' && v !== null) || typeof v === 'function') FORBIDDEN.add(v);\n}\n\n/* the functions stored on an object (values and accessors) */\nfunction forbidMembers(o: object): void {\n for (const k of Reflect.ownKeys(o)) {\n const d = Reflect.getOwnPropertyDescriptor(o, k);\n if (!d) continue;\n if (typeof d.value === 'function') forbid(d.value);\n forbid(d.get);\n forbid(d.set);\n }\n}\n\n(function collectIntrinsics() {\n const g = globalThis as Record<string, unknown>;\n for (const v of [Function, AsyncFunction, GeneratorFunction, AsyncGeneratorFunction, eval, globalThis, Reflect, Proxy, Object]) forbid(v);\n /* the host error constructors expose stack-trace hooks (captureStackTrace,\n prepareStackTrace) that can hand out host frames */\n for (const name of ['Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',\n 'AggregateError', 'SuppressedError']) forbid(g[name]);\n /* the prototype of every standard constructor */\n const ctors = ['Object', 'Function', 'Array', 'String', 'Number', 'Boolean', 'Symbol', 'BigInt', 'Error', 'EvalError',\n 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'AggregateError', 'SuppressedError', 'Date',\n 'RegExp', 'Map', 'Set', 'WeakMap', 'WeakSet', 'WeakRef', 'FinalizationRegistry', 'Promise', 'ArrayBuffer',\n 'SharedArrayBuffer', 'DataView', 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array',\n 'Int32Array', 'Uint32Array', 'Float16Array', 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array',\n 'Iterator', 'AsyncIterator', 'DisposableStack', 'AsyncDisposableStack'];\n for (const name of ctors) {\n const c = g[name] as { prototype?: unknown } | undefined;\n if (typeof c === 'function') forbid(c.prototype);\n }\n const TypedArray = Object.getPrototypeOf(Int8Array) as Function;\n forbid(TypedArray); forbid(TypedArray.prototype);\n for (const F of [AsyncFunction, GeneratorFunction, AsyncGeneratorFunction]) {\n forbid(F.prototype); /* %AsyncFunction.prototype%, %GeneratorFunction.prototype%, ... */\n forbid((F.prototype as { prototype?: unknown }).prototype); /* %GeneratorPrototype%, %AsyncGeneratorPrototype% */\n }\n const arrayIter = Object.getPrototypeOf([][Symbol.iterator]());\n forbid(arrayIter);\n forbid(Object.getPrototypeOf(arrayIter)); /* %IteratorPrototype% */\n forbid(Object.getPrototypeOf(Object.getPrototypeOf((async function* () {})()))); /* %AsyncGeneratorPrototype% */\n forbid(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf((async function* () {})())))); /* %AsyncIteratorPrototype% */\n forbid(Object.getPrototypeOf(new Map().entries()));\n forbid(Object.getPrototypeOf(new Set().values()));\n forbid(Object.getPrototypeOf(''[Symbol.iterator]()));\n forbid(Object.getPrototypeOf(/a/[Symbol.matchAll]('a')));\n /* %ThrowTypeError% and the methods that reach code, prototypes or properties\n of arbitrary objects */\n forbid(Reflect.getOwnPropertyDescriptor(Function.prototype, 'caller')?.get);\n for (const o of [Object, Reflect, Proxy, Object.prototype, Function.prototype]) forbidMembers(o);\n})();\n\nconst BLOCKED_KEYS = new Set<PropertyKey>([\n 'constructor', 'prototype', '__proto__', 'caller', 'callee', 'arguments',\n '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__',\n]);\n\nconst WELL_KNOWN_SYMBOLS = new Set<symbol>(\n Reflect.ownKeys(Symbol).map(k => (Symbol as unknown as Record<PropertyKey, unknown>)[k])\n .filter((v): v is symbol => typeof v === 'symbol'));\n/* the well-known symbols forwarded as keys */\nconst FORWARDED_SYMBOLS = new Set<symbol>([Symbol.iterator, Symbol.asyncIterator, Symbol.toStringTag, Symbol.toPrimitive]);\n\nconst ERROR_KINDS: [Function, JSErrorEnum][] = [\n [TypeError, JSErrorEnum.TYPE_ERROR], [RangeError, JSErrorEnum.RANGE_ERROR], [SyntaxError, JSErrorEnum.SYNTAX_ERROR],\n [ReferenceError, JSErrorEnum.REFERENCE_ERROR], [URIError, JSErrorEnum.URI_ERROR], [EvalError, JSErrorEnum.EVAL_ERROR],\n];\nconst STANDARD_ERROR_NAMES = new Set(['Error', 'TypeError', 'RangeError', 'SyntaxError', 'ReferenceError', 'URIError', 'EvalError']);\n\nfunction isHostConstructor(f: Function): boolean {\n try {\n Reflect.construct(String, [], f);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isObjectLike(v: unknown): v is object {\n return (typeof v === 'object' && v !== null) || typeof v === 'function';\n}\n\n/* ------------------------------------------------------------------ */\n/* registries shared by every membrane */\n\n/* membrane proxy -> the host object it stands for */\nconst proxyHost = new WeakMap<object, { host: object; membrane: Membrane }>();\n/* host callable made for a guest function -> that guest function */\nconst callableGuest = new WeakMap<Function, JSValue>();\n/* host Error thrown to host code for a guest exception -> the guest exception */\nconst thrownGuest = new WeakMap<object, JSValue>();\n/* one membrane per context and policy */\nconst membranes = new WeakMap<JSContext, { plain?: Membrane; byPolicy: WeakMap<MembranePolicy, Membrane> }>();\n/* membrane traps running now, per runtime. Compiled guest code pushes no interpreter frame, so\n when it calls into host code through a proxy, `rt.current_stack_frame` is null although guest\n code is on the stack; this count is what tells a guest callback the host calls back that it is\n not the outermost call */\nconst trapDepth = new WeakMap<object, number>();\n\nfunction membraneFor(ctx: JSContext, policy: MembranePolicy | undefined): Membrane {\n let e = membranes.get(ctx);\n if (!e) { e = { byPolicy: new WeakMap() }; membranes.set(ctx, e); }\n if (policy === undefined) return (e.plain ??= new Membrane(ctx, {}));\n let m = e.byPolicy.get(policy);\n if (!m) { m = new Membrane(ctx, policy); e.byPolicy.set(policy, m); }\n return m;\n}\n\n/* ------------------------------------------------------------------ */\n\nclass Membrane {\n private readonly proxies = new WeakMap<object, object>(); /* host object -> proxy */\n private readonly callables = new WeakMap<object, Function>(); /* guest function -> host callable */\n private readonly hasInstanceFns = new WeakMap<object, JSValue>();\n private readonly guestSymbols = new WeakSet<symbol>(); /* symbols the guest handed to the host */\n private readonly writable: boolean;\n private readonly allowFn: ((target: object, key: PropertyKey) => boolean) | undefined;\n\n constructor(readonly ctx: JSContext, policy: MembranePolicy) {\n this.writable = policy.writable === true;\n this.allowFn = typeof policy.allow === 'function' ? policy.allow.bind(policy) : undefined;\n }\n\n /* ---------------- host -> guest ---------------- */\n\n toGuest(v: unknown, seen?: Map<object, JSValue>): JSValue {\n switch (typeof v) {\n case 'undefined': case 'boolean': case 'number': case 'string': case 'bigint':\n return v as JSValue;\n case 'symbol':\n return this.symbolCrosses(v) ? v : undefined;\n }\n if (v === null) return null;\n const o = v as object;\n if (FORBIDDEN.has(o)) return undefined;\n const p = proxyHost.get(o);\n if (p !== undefined) return p.membrane.ctx === this.ctx ? o : this.toGuest(p.host, seen);\n if (typeof o === 'function') {\n const g = callableGuest.get(o);\n if (g !== undefined) return g;\n }\n if (this.isGuestOwned(o)) return o;\n if (o instanceof Promise) {\n return hostPromiseWith(this.ctx, o, r => this.toGuest(r), e => this.thrownToGuest(e));\n }\n if (Array.isArray(o)) {\n /* arrays are snapshots: a fresh guest array whose elements are converted */\n seen ??= new Map();\n const cached = seen.get(o);\n if (cached !== undefined) return cached;\n const arr = JS_NewArrayFrom(this.ctx, []) as unknown as JSValue[];\n seen.set(o, arr);\n const len = o.length;\n for (let i = 0; i < len; i++) arr[i] = this.toGuest(o[i], seen);\n return arr;\n }\n if (o instanceof Date) return JS_NewDate(this.ctx, Date.prototype.getTime.call(o));\n if (o instanceof Error) return this.errorToGuest(o);\n if (o instanceof RegExp || o instanceof ArrayBuffer || ArrayBuffer.isView(o)) return toGuest(this.ctx, o);\n return this.wrap(o);\n }\n\n /* a well-known or registered symbol, or one the guest gave to the host */\n private symbolCrosses(s: symbol): boolean {\n return WELL_KNOWN_SYMBOLS.has(s) || Symbol.keyFor(s) !== undefined || this.guestSymbols.has(s);\n }\n\n /* an engine object, or an object whose prototype chain reaches this\n context's guest Object.prototype / Function.prototype */\n private isGuestOwned(o: object): boolean {\n if (js_meta.has(o)) return true;\n try {\n return this.chainReachesGuest(o);\n } catch {\n return false; /* a host proxy whose getPrototypeOf throws */\n }\n }\n\n private chainReachesGuest(o: object): boolean {\n const ctx = this.ctx;\n const op = ctx.class_proto[JSClassID.OBJECT], fp = ctx.function_proto;\n let p: object | null = Reflect.getPrototypeOf(o);\n for (let i = 0; i < 64 && p !== null; i++) {\n if (p === op || p === fp) return true;\n if (WALK_STOP.has(p) || FORBIDDEN.has(p) || proxyHost.has(p)) return false;\n p = Reflect.getPrototypeOf(p);\n }\n return false;\n }\n\n private errorToGuest(e: Error): JSValue {\n let kind = JSErrorEnum.PLAIN_ERROR;\n for (const [C, k] of ERROR_KINDS) if (e instanceof C) { kind = k; break; }\n let message = '', name: unknown;\n try { const m = e.message; message = typeof m === 'string' ? m : ''; name = e.name; } catch { /* hostile getter */ }\n const g = JS_NewErrorNative(this.ctx, kind, message);\n if (kind === JSErrorEnum.PLAIN_ERROR && typeof name === 'string' && !STANDARD_ERROR_NAMES.has(name)) {\n Reflect.defineProperty(g, 'name', { value: name, writable: true, enumerable: false, configurable: true });\n }\n return g;\n }\n\n /* convert anything the host threw into a value to throw in the guest; the\n host exception object itself never crosses */\n thrownToGuest(e: unknown): JSValue {\n if (isObjectLike(e)) {\n const g = thrownGuest.get(e);\n if (g !== undefined) return g; /* a guest exception that passed through host code */\n if (proxyHost.has(e) || this.isGuestOwned(e)) return e as JSValue; /* thrown by guest code */\n if (e instanceof Error) return this.errorToGuest(e);\n let message = 'host exception';\n try {\n const m = (e as { message?: unknown }).message;\n if (typeof m === 'string') message = m;\n } catch { /* hostile getter */ }\n return JS_NewErrorNative(this.ctx, JSErrorEnum.PLAIN_ERROR, message);\n }\n if (typeof e === 'symbol') return this.symbolCrosses(e) ? e : undefined;\n return e as JSValue;\n }\n\n private guestTypeError(message: string): JSValue {\n return JS_NewErrorNative(this.ctx, JSErrorEnum.TYPE_ERROR, message);\n }\n\n /* the proxy for a host object (one per host object) */\n wrap(host: object): object {\n const cached = this.proxies.get(host);\n if (cached !== undefined) return cached;\n let target: object;\n const callable = typeof host === 'function';\n if (callable) {\n /* constructible or not like the host function; no own properties, so\n no target invariant constrains the traps */\n const f: Function = isHostConstructor(host as Function) ? Function.prototype.bind.call(function () {}, null) : () => {};\n Reflect.deleteProperty(f, 'name');\n Reflect.deleteProperty(f, 'length');\n Reflect.setPrototypeOf(f, null);\n target = f;\n } else {\n target = Object.create(null);\n }\n const proxy = new Proxy(target, this.handler(host, callable));\n this.proxies.set(host, proxy);\n proxyHost.set(proxy, { host, membrane: this });\n return proxy;\n }\n\n private keyAllowed(host: object, key: PropertyKey): boolean {\n if (typeof key === 'symbol') {\n if (WELL_KNOWN_SYMBOLS.has(key) && !FORWARDED_SYMBOLS.has(key)) return false;\n } else if (BLOCKED_KEYS.has(key)) {\n return false;\n }\n return this.allowFn === undefined || this.allowFn(host, key) === true;\n }\n\n /* listed by ownKeys: host symbols other than the forwarded well-known ones stay hidden */\n private keyListed(host: object, key: string | symbol): boolean {\n if (typeof key === 'symbol' && !FORWARDED_SYMBOLS.has(key) && !this.guestSymbols.has(key)) return false;\n return this.keyAllowed(host, key);\n }\n\n /* walk the host prototype chain up to (not including) the host\n Object.prototype / Function.prototype */\n private lookup(host: object, key: PropertyKey): PropertyDescriptor | undefined {\n let o: object | null = host;\n for (let depth = 0; o !== null && depth < 10000; depth++) {\n if (WALK_STOP.has(o)) return undefined;\n const d = Reflect.getOwnPropertyDescriptor(o, key);\n if (d !== undefined) return d;\n o = Reflect.getPrototypeOf(o);\n }\n return undefined;\n }\n\n private hostOf(v: unknown, fallback: object): object {\n return isObjectLike(v) ? proxyHost.get(v)?.host ?? fallback : fallback;\n }\n\n private hasInstance(host: object): JSValue {\n let f = this.hasInstanceFns.get(host);\n if (f === undefined) {\n f = JS_NewCFunction(this.ctx, (ctx, _this, argv) => {\n const v = argv[0];\n const h = isObjectLike(v) ? proxyHost.get(v)?.host : undefined;\n if (h === undefined) return false;\n try {\n return h instanceof (host as Function);\n } catch (e) {\n return JS_Throw(ctx, this.thrownToGuest(e));\n }\n }, '[Symbol.hasInstance]', 1);\n this.hasInstanceFns.set(host, f);\n }\n return f;\n }\n\n private handler(host: object, callable: boolean): ProxyHandler<object> {\n const m = this;\n const ctx = this.ctx;\n const guestProto = () => (callable ? ctx.function_proto : ctx.class_proto[JSClassID.OBJECT]) as object;\n /* every trap converts what the host throws, and counts as guest code on the stack while it\n runs host code */\n const rt = ctx.rt;\n const guard = <A extends unknown[], R>(fn: (...args: A) => R) => (...args: A): R => {\n trapDepth.set(rt, (trapDepth.get(rt) ?? 0) + 1);\n try {\n return fn(...args);\n } catch (e) {\n throw m.thrownToGuest(e);\n } finally {\n trapDepth.set(rt, trapDepth.get(rt)! - 1);\n }\n };\n const refuse = (what: string, key?: PropertyKey): never => {\n const k = key === undefined ? '' : ` '${typeof key === 'symbol' ? key.description ?? 'symbol' : key}'`;\n throw m.guestTypeError(`cannot ${what}${k}: host object is read-only`);\n };\n const proxyOf = () => m.proxies.get(host);\n\n return {\n get: guard((_t: object, key: PropertyKey, receiver: unknown) => {\n if (callable && key === Symbol.hasInstance) return m.hasInstance(host);\n if (!m.keyAllowed(host, key)) return undefined;\n const d = m.lookup(host, key);\n if (d === undefined) return Reflect.get(guestProto(), key, receiver);\n if ('value' in d) return m.toGuest(d.value);\n if (d.get === undefined) return undefined;\n return m.toGuest(Reflect.apply(d.get, m.hostOf(receiver, host), []));\n }),\n has: guard((_t: object, key: PropertyKey) => {\n if (callable && key === Symbol.hasInstance) return true;\n if (!m.keyAllowed(host, key)) return false;\n if (m.lookup(host, key) !== undefined) return true;\n return Reflect.has(guestProto(), key);\n }),\n ownKeys: guard((_t: object) => Reflect.ownKeys(host).filter(k => m.keyListed(host, k))),\n getOwnPropertyDescriptor: guard((_t: object, key: PropertyKey) => {\n if (!m.keyAllowed(host, key)) return undefined;\n const d = Reflect.getOwnPropertyDescriptor(host, key);\n if (d === undefined) return undefined;\n if ('value' in d) {\n return { value: m.toGuest(d.value), writable: m.writable && d.writable === true, enumerable: d.enumerable === true, configurable: true };\n }\n return {\n get: d.get === undefined ? undefined : m.toGuest(d.get) as (() => unknown) | undefined,\n set: d.set === undefined || !m.writable ? undefined : m.toGuest(d.set) as ((v: unknown) => void) | undefined,\n enumerable: d.enumerable === true, configurable: true,\n };\n }),\n set: guard((_t: object, key: PropertyKey, value: unknown, receiver: unknown) => {\n if (receiver !== proxyOf() && !(isObjectLike(receiver) && proxyHost.has(receiver))) {\n /* a guest object inheriting from the proxy: the property lands on it */\n return Reflect.defineProperty(receiver as object, key, { value, writable: true, enumerable: true, configurable: true });\n }\n if (!m.writable || !m.keyAllowed(host, key)) refuse('assign to property', key);\n return Reflect.set(host, key, m.fromGuest(value as JSValue), m.hostOf(receiver, host));\n }),\n defineProperty: guard((_t: object, key: PropertyKey, desc: PropertyDescriptor) => {\n if (!m.writable || !m.keyAllowed(host, key)) refuse('define property', key);\n if (desc.configurable === false) throw m.guestTypeError('cannot define a non-configurable property on a host object');\n const hd: PropertyDescriptor = {};\n if ('value' in desc) hd.value = m.fromGuest(desc.value as JSValue);\n if ('get' in desc) hd.get = m.fromGuest(desc.get as JSValue) as () => unknown;\n if ('set' in desc) hd.set = m.fromGuest(desc.set as JSValue) as (v: unknown) => void;\n if ('writable' in desc) hd.writable = desc.writable;\n if ('enumerable' in desc) hd.enumerable = desc.enumerable;\n hd.configurable = true;\n return Reflect.defineProperty(host, key, hd);\n }),\n deleteProperty: guard((_t: object, key: PropertyKey) => {\n if (!m.writable || !m.keyAllowed(host, key)) refuse('delete property', key);\n return Reflect.deleteProperty(host, key);\n }),\n getPrototypeOf: () => guestProto(),\n setPrototypeOf: () => false,\n isExtensible: () => true,\n preventExtensions: () => false,\n apply: guard((_t: object, thisArg: unknown, args: unknown[]) => {\n const hostThis = thisArg === ctx.global_obj ? undefined : m.fromGuest(thisArg as JSValue);\n const hostArgs = args.map(a => m.fromGuest(a as JSValue));\n return m.toGuest(Reflect.apply(host as Function, hostThis, hostArgs));\n }),\n construct: guard((_t: object, args: unknown[], newTarget: unknown) => {\n if (newTarget !== proxyOf()) throw m.guestTypeError('host constructors cannot be subclassed from the guest');\n const r = m.toGuest(Reflect.construct(host as Function, args.map(a => m.fromGuest(a as JSValue))));\n if (!isObjectLike(r)) throw m.guestTypeError('host constructor returned a value that cannot cross the membrane');\n return r;\n }),\n };\n }\n\n /* ---------------- guest -> host ---------------- */\n\n fromGuest(v: JSValue): unknown {\n return fromGuestWith(this.ctx, v, x => this.fromGuestHook(x));\n }\n\n private fromGuestHook(v: JSValue): unknown {\n if (typeof v === 'symbol') {\n if (!WELL_KNOWN_SYMBOLS.has(v) && Symbol.keyFor(v) === undefined) this.guestSymbols.add(v);\n return v;\n }\n if (!isObjectLike(v)) return FROM_GUEST_DEFAULT;\n const p = proxyHost.get(v);\n if (p !== undefined) return p.host;\n if (typeof v === 'function') return this.callable(v);\n if (JS_GetClassID(v) === JSClassID.PROMISE) {\n return guestPromiseToHostWith(this.ctx, v, x => this.fromGuest(x),\n e => (JS_GetClassID(e) === JSClassID.ERROR ? guestErrorToHost(this.ctx, e) : this.fromGuest(e)));\n }\n return FROM_GUEST_DEFAULT;\n }\n\n /* a host function that runs the guest function (one per guest function) */\n private callable(fn: JSValue): Function {\n const cached = this.callables.get(fn as object);\n if (cached !== undefined) return cached;\n const m = this;\n const ctx = this.ctx;\n const c = {\n guestCallback(this: unknown, ...args: unknown[]): unknown {\n /* outermost: no guest code below this call, neither an interpreter frame nor a membrane\n trap (the way compiled guest code reaches host code) */\n const outermost = ctx.rt.current_stack_frame === null && (trapDepth.get(ctx.rt) ?? 0) === 0;\n try {\n const r = JS_Call(ctx, fn, m.toGuest(this), args.map(a => m.toGuest(a)));\n if (JS_IsException(r)) {\n const exc = JS_GetException(ctx);\n const he = guestErrorToHost(ctx, exc);\n thrownGuest.set(he, exc);\n throw he;\n }\n return m.fromGuest(r);\n } finally {\n /* called from host code outside any guest call (an event, a timer, a\n promise reaction): run the guest jobs the callback queued */\n if (outermost) drainJobs(ctx);\n }\n },\n }.guestCallback;\n this.callables.set(fn as object, c);\n callableGuest.set(c, fn);\n return c;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* public API */\n\n/** the guest view of a host value: primitives as is, host objects and\n * functions as live membrane proxies (see docs/MEMBRANE.md) */\nexport function toGuestLive(ctx: JSContext, value: unknown, policy?: MembranePolicy): JSValue {\n if (FORBIDDEN.has(value)) throw new TypeError('toGuestLive: refusing to hand a host intrinsic to the guest');\n return membraneFor(ctx, policy).toGuest(value);\n}\n\n/** define the global `name` in the guest as a live view of `root` */\nexport function exposeLive(ctx: JSContext, name: string, root: unknown, policy?: MembranePolicy): void {\n const g = toGuestLive(ctx, root, policy);\n if (JS_SetPropertyStr(ctx, ctx.global_obj, name, g) < 0) {\n throw guestErrorToHost(ctx, JS_GetException(ctx));\n }\n}\n\n/** true if `value` is a membrane proxy */\nexport function isLiveProxy(value: unknown): boolean {\n return isObjectLike(value) && proxyHost.has(value);\n}\n"]}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const JSEPTION_VERSION = "0.0.4";
1
+ export declare const JSEPTION_VERSION = "0.0.5";
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* The jseption package version, kept equal to package.json by the npm "version" script
2
2
  (scripts/sync-version.mjs) and checked by tests/bytecode.test.ts. Serialized bytecode
3
3
  records it and only loads in the same version. */
4
- export const JSEPTION_VERSION = '0.0.4';
4
+ export const JSEPTION_VERSION = '0.0.5';
5
5
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;oDAEoD;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC","sourcesContent":["/* The jseption package version, kept equal to package.json by the npm \"version\" script\n (scripts/sync-version.mjs) and checked by tests/bytecode.test.ts. Serialized bytecode\n records it and only loads in the same version. */\nexport const JSEPTION_VERSION = '0.0.4';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;oDAEoD;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC","sourcesContent":["/* The jseption package version, kept equal to package.json by the npm \"version\" script\n (scripts/sync-version.mjs) and checked by tests/bytecode.test.ts. Serialized bytecode\n records it and only loads in the same version. */\nexport const JSEPTION_VERSION = '0.0.5';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jseption",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "A sandboxed JavaScript engine for any JavaScript host, built on a TypeScript port of QuickJS with a bytecode-to-JavaScript compiler",
5
5
  "keywords": [
6
6
  "quickjs",