jseption 0.0.6 → 0.0.7
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 +5 -2
- package/dist/builtins/typedarray.d.ts +3 -1
- package/dist/builtins/typedarray.js +23 -5
- package/dist/builtins/typedarray.js.map +1 -1
- package/dist/embed.d.ts +5 -0
- package/dist/embed.js +33 -8
- package/dist/embed.js.map +1 -1
- package/dist/membrane.d.ts +6 -0
- package/dist/membrane.js +6 -2
- package/dist/membrane.js.map +1 -1
- 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
|
@@ -200,7 +200,9 @@ const data = fromGuest(ctx, value); // guest object graph -> plain ho
|
|
|
200
200
|
```
|
|
201
201
|
|
|
202
202
|
Primitives cross unchanged. `toGuest` copies objects, arrays, Date, RegExp, Map, Set,
|
|
203
|
-
typed arrays and Errors into guest equivalents
|
|
203
|
+
typed arrays and Errors into guest equivalents (a `SharedArrayBuffer`, or any buffer with
|
|
204
|
+
`{ liveBuffers: true }`, is handed over as the host memory itself, so a WebAssembly
|
|
205
|
+
module's memory can be read and written from the guest), wraps host functions in guest functions
|
|
204
206
|
(host exceptions become guest errors, returned promises are bridged, guest promise jobs
|
|
205
207
|
run when they settle) and preserves shared references and cycles. `fromGuest` does the
|
|
206
208
|
reverse, turning guest functions into host functions that call into the guest. See
|
|
@@ -224,7 +226,8 @@ exposeLive(ctx, 'store', store, { writable: true, allow: (target, key) => key !=
|
|
|
224
226
|
```
|
|
225
227
|
|
|
226
228
|
Primitives cross as values, host arrays as snapshot guest arrays, `Date`/`RegExp`/typed
|
|
227
|
-
arrays/errors as copies,
|
|
229
|
+
arrays/errors as copies (shared memory, and any buffer under a `liveBuffers` policy, as
|
|
230
|
+
the memory itself), promises as guest promises; guest arguments are copied
|
|
228
231
|
(`fromGuest`), a proxy passed back is unwrapped to its host object, and guest callbacks
|
|
229
232
|
become host functions. The sandbox rules are always on: host intrinsics (`Function`,
|
|
230
233
|
`eval`, `globalThis`, `Object`, `Reflect`, `Proxy`, the intrinsic prototypes, ...) never
|
|
@@ -4,8 +4,10 @@ export declare class JSArrayBufferData extends JSArrayBuffer {
|
|
|
4
4
|
max_byte_length: number;
|
|
5
5
|
dv: DataView | null;
|
|
6
6
|
dv_data: Uint8Array | null;
|
|
7
|
-
constructor(len: number, shared: boolean, max_len: number);
|
|
7
|
+
constructor(len: number, shared: boolean, max_len: number, existing?: ArrayBuffer | SharedArrayBuffer);
|
|
8
8
|
}
|
|
9
|
+
export declare function isSharedArrayBuffer(v: unknown): v is SharedArrayBuffer;
|
|
10
|
+
export declare function JS_NewArrayBufferFrom(ctx: JSContext, buffer: ArrayBuffer | SharedArrayBuffer): JSValue;
|
|
9
11
|
export declare function JS_NewArrayBufferCopy(ctx: JSContext, buf: Uint8Array): JSValue;
|
|
10
12
|
export declare function JS_DetachArrayBuffer(ctx: JSContext, obj: JSValue): void;
|
|
11
13
|
export declare function is_typed_array_class(class_id: JSClassID): boolean;
|
|
@@ -44,16 +44,21 @@ export function typed_array_class_available(class_id) {
|
|
|
44
44
|
--------------------------------------------------------------------- */
|
|
45
45
|
/* array buffer data with the resizable extension. The host buffer is
|
|
46
46
|
resizable (growable when shared) when max_len >= 0; 'data' is a length
|
|
47
|
-
tracking view over it.
|
|
47
|
+
tracking view over it. With 'existing', the guest buffer is that host
|
|
48
|
+
buffer itself (JS_NewArrayBufferFrom): the two sides share the bytes. */
|
|
48
49
|
export class JSArrayBufferData extends JSArrayBuffer {
|
|
49
50
|
/* maximum byte length for resizable buffers, -1 otherwise */
|
|
50
51
|
max_byte_length = -1;
|
|
51
52
|
/* cached host DataView over 'data' */
|
|
52
53
|
dv = null;
|
|
53
54
|
dv_data = null;
|
|
54
|
-
constructor(len, shared, max_len) {
|
|
55
|
+
constructor(len, shared, max_len, existing) {
|
|
55
56
|
let buffer;
|
|
56
|
-
if (
|
|
57
|
+
if (existing) {
|
|
58
|
+
buffer = existing;
|
|
59
|
+
max_len = (shared ? existing.growable : existing.resizable) ? existing.maxByteLength : -1;
|
|
60
|
+
}
|
|
61
|
+
else if (shared)
|
|
57
62
|
buffer = max_len >= 0 ? new SharedArrayBuffer(len, { maxByteLength: max_len }) : new SharedArrayBuffer(len);
|
|
58
63
|
else
|
|
59
64
|
buffer = max_len >= 0 ? new ArrayBuffer(len, { maxByteLength: max_len }) : new ArrayBuffer(len);
|
|
@@ -61,6 +66,10 @@ export class JSArrayBufferData extends JSArrayBuffer {
|
|
|
61
66
|
this.max_byte_length = max_len;
|
|
62
67
|
}
|
|
63
68
|
}
|
|
69
|
+
/* a host SharedArrayBuffer, where the host has one */
|
|
70
|
+
export function isSharedArrayBuffer(v) {
|
|
71
|
+
return typeof SharedArrayBuffer === 'function' && v instanceof SharedArrayBuffer;
|
|
72
|
+
}
|
|
64
73
|
function array_buffer_get_dv(abuf) {
|
|
65
74
|
const a = abuf;
|
|
66
75
|
if (a.dv === null || a.dv_data !== abuf.data) {
|
|
@@ -87,7 +96,7 @@ function JS_ThrowTypeErrorArrayBufferOOB(ctx) {
|
|
|
87
96
|
}
|
|
88
97
|
/* XXX: we are currently limited to 2 GB */
|
|
89
98
|
const ARRAY_BUFFER_MAX_LENGTH = 0x7fffffff;
|
|
90
|
-
function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, buf) {
|
|
99
|
+
function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, buf, existing) {
|
|
91
100
|
const obj = js_create_from_ctor(ctx, new_target, class_id);
|
|
92
101
|
if (JS_IsException(obj))
|
|
93
102
|
return obj;
|
|
@@ -95,12 +104,21 @@ function js_array_buffer_constructor3(ctx, new_target, len, max_len, class_id, b
|
|
|
95
104
|
return JS_ThrowRangeError(ctx, 'invalid array buffer length');
|
|
96
105
|
if (max_len > ARRAY_BUFFER_MAX_LENGTH)
|
|
97
106
|
return JS_ThrowRangeError(ctx, 'invalid array buffer maximum length');
|
|
98
|
-
const abuf = new JSArrayBufferData(len, class_id === 20 /* JSClassID.SHARED_ARRAY_BUFFER */, max_len);
|
|
107
|
+
const abuf = new JSArrayBufferData(len, class_id === 20 /* JSClassID.SHARED_ARRAY_BUFFER */, max_len, existing);
|
|
99
108
|
if (buf)
|
|
100
109
|
abuf.data.set(buf.subarray(0, len));
|
|
101
110
|
Q.JS_SetOpaque(obj, abuf);
|
|
102
111
|
return obj;
|
|
103
112
|
}
|
|
113
|
+
/* a guest ArrayBuffer (or SharedArrayBuffer) over the host buffer itself, not a
|
|
114
|
+
copy: what the guest writes the host sees, and the other way round. A
|
|
115
|
+
buffer is bytes: it reaches no host object, so sharing it keeps the
|
|
116
|
+
sandbox rules (its guest prototype is the guest's). The guest cannot
|
|
117
|
+
detach, resize or transfer it beyond what the host buffer allows. */
|
|
118
|
+
export function JS_NewArrayBufferFrom(ctx, buffer) {
|
|
119
|
+
const shared = isSharedArrayBuffer(buffer);
|
|
120
|
+
return js_array_buffer_constructor3(ctx, undefined, buffer.byteLength, -1, shared ? 20 /* JSClassID.SHARED_ARRAY_BUFFER */ : 19 /* JSClassID.ARRAY_BUFFER */, null, buffer);
|
|
121
|
+
}
|
|
104
122
|
function js_array_buffer_constructor2(ctx, new_target, len, class_id) {
|
|
105
123
|
return js_array_buffer_constructor3(ctx, new_target, len, -1, class_id, null);
|
|
106
124
|
}
|