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 +31 -0
- package/dist/embed.d.ts +5 -0
- package/dist/embed.js +44 -12
- package/dist/embed.js.map +1 -1
- package/dist/jseption.d.ts +2 -0
- package/dist/jseption.js +1 -0
- package/dist/jseption.js.map +1 -1
- package/dist/membrane.d.ts +16 -0
- package/dist/membrane.js +576 -0
- package/dist/membrane.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
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 = (
|
|
185
|
+
const settle = (ok, v) => {
|
|
186
|
+
let fn = ok ? funcs[0] : funcs[1];
|
|
180
187
|
let g;
|
|
181
188
|
try {
|
|
182
|
-
g =
|
|
189
|
+
g = ok ? resolve(v) : reject(v);
|
|
183
190
|
}
|
|
184
191
|
catch (e) {
|
|
185
192
|
fn = funcs[1];
|
|
186
|
-
g =
|
|
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(
|
|
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
|
|
274
|
-
|
|
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"]}
|
package/dist/jseption.d.ts
CHANGED
|
@@ -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 */
|
package/dist/jseption.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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';\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;
|
package/dist/membrane.js
ADDED
|
@@ -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.
|
|
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
|
+
export const JSEPTION_VERSION = '0.0.5';
|
|
5
5
|
//# sourceMappingURL=version.js.map
|
package/dist/version.js.map
CHANGED
|
@@ -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.
|
|
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