Skip to content

Commit fdeefea

Browse files
Merge pull request #323 from swiftwasm/katei/move-runtime-files-template
Place the runtime JS files beside the template files
2 parents 55ca25a + 5d69e81 commit fdeefea

File tree

7 files changed

+1934
-1929
lines changed

7 files changed

+1934
-1929
lines changed

Makefile

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,6 @@ perf-tester:
3939
.PHONY: regenerate_swiftpm_resources
4040
regenerate_swiftpm_resources:
4141
npm run build
42-
cp Runtime/lib/index.js Runtime/lib/index.mjs Runtime/lib/index.d.ts Sources/JavaScriptKit/Runtime
42+
cp Runtime/lib/index.js Plugins/PackageToJS/Templates/runtime.js
43+
cp Runtime/lib/index.mjs Plugins/PackageToJS/Templates/runtime.mjs
44+
cp Runtime/lib/index.d.ts Plugins/PackageToJS/Templates/runtime.d.ts
+264
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
declare class Memory {
2+
readonly rawMemory: WebAssembly.Memory;
3+
private readonly heap;
4+
constructor(exports: WebAssembly.Exports);
5+
retain: (value: any) => number;
6+
getObject: (ref: number) => any;
7+
release: (ref: number) => void;
8+
bytes: () => Uint8Array<ArrayBuffer>;
9+
dataView: () => DataView<ArrayBuffer>;
10+
writeBytes: (ptr: pointer, bytes: Uint8Array) => void;
11+
readUint32: (ptr: pointer) => number;
12+
readUint64: (ptr: pointer) => bigint;
13+
readInt64: (ptr: pointer) => bigint;
14+
readFloat64: (ptr: pointer) => number;
15+
writeUint32: (ptr: pointer, value: number) => void;
16+
writeUint64: (ptr: pointer, value: bigint) => void;
17+
writeInt64: (ptr: pointer, value: bigint) => void;
18+
writeFloat64: (ptr: pointer, value: number) => void;
19+
}
20+
21+
declare const enum Kind {
22+
Boolean = 0,
23+
String = 1,
24+
Number = 2,
25+
Object = 3,
26+
Null = 4,
27+
Undefined = 5,
28+
Function = 6,
29+
Symbol = 7,
30+
BigInt = 8
31+
}
32+
33+
type ref = number;
34+
type pointer = number;
35+
type bool = number;
36+
type JavaScriptValueKind = number;
37+
type JavaScriptValueKindAndFlags = number;
38+
interface ImportedFunctions {
39+
swjs_set_prop(ref: number, name: number, kind: Kind, payload1: number, payload2: number): void;
40+
swjs_get_prop(ref: number, name: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKind;
41+
swjs_set_subscript(ref: number, index: number, kind: Kind, payload1: number, payload2: number): void;
42+
swjs_get_subscript(ref: number, index: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKind;
43+
swjs_encode_string(ref: number, bytes_ptr_result: pointer): number;
44+
swjs_decode_string(bytes_ptr: pointer, length: number): number;
45+
swjs_load_string(ref: number, buffer: pointer): void;
46+
swjs_call_function(ref: number, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags;
47+
swjs_call_function_no_catch(ref: number, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags;
48+
swjs_call_function_with_this(obj_ref: ref, func_ref: ref, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags;
49+
swjs_call_function_with_this_no_catch(obj_ref: ref, func_ref: ref, argv: pointer, argc: number, payload1_ptr: pointer, payload2_ptr: pointer): JavaScriptValueKindAndFlags;
50+
swjs_call_new(ref: number, argv: pointer, argc: number): number;
51+
swjs_call_throwing_new(ref: number, argv: pointer, argc: number, exception_kind_ptr: pointer, exception_payload1_ptr: pointer, exception_payload2_ptr: pointer): number;
52+
swjs_instanceof(obj_ref: ref, constructor_ref: ref): boolean;
53+
swjs_value_equals(lhs_ref: ref, rhs_ref: ref): boolean;
54+
swjs_create_function(host_func_id: number, line: number, file: ref): number;
55+
swjs_create_typed_array(constructor_ref: ref, elementsPtr: pointer, length: number): number;
56+
swjs_create_object(): number;
57+
swjs_load_typed_array(ref: ref, buffer: pointer): void;
58+
swjs_release(ref: number): void;
59+
swjs_release_remote(tid: number, ref: number): void;
60+
swjs_i64_to_bigint(value: bigint, signed: bool): ref;
61+
swjs_bigint_to_i64(ref: ref, signed: bool): bigint;
62+
swjs_i64_to_bigint_slow(lower: number, upper: number, signed: bool): ref;
63+
swjs_unsafe_event_loop_yield: () => void;
64+
swjs_send_job_to_main_thread: (unowned_job: number) => void;
65+
swjs_listen_message_from_main_thread: () => void;
66+
swjs_wake_up_worker_thread: (tid: number) => void;
67+
swjs_listen_message_from_worker_thread: (tid: number) => void;
68+
swjs_terminate_worker_thread: (tid: number) => void;
69+
swjs_get_worker_thread_id: () => number;
70+
swjs_request_sending_object: (sending_object: ref, transferring_objects: pointer, transferring_objects_count: number, object_source_tid: number, sending_context: pointer) => void;
71+
swjs_request_sending_objects: (sending_objects: pointer, sending_objects_count: number, transferring_objects: pointer, transferring_objects_count: number, object_source_tid: number, sending_context: pointer) => void;
72+
}
73+
74+
/**
75+
* A thread channel is a set of functions that are used to communicate between
76+
* the main thread and the worker thread. The main thread and the worker thread
77+
* can send messages to each other using these functions.
78+
*
79+
* @example
80+
* ```javascript
81+
* // worker.js
82+
* const runtime = new SwiftRuntime({
83+
* threadChannel: {
84+
* postMessageToMainThread: postMessage,
85+
* listenMessageFromMainThread: (listener) => {
86+
* self.onmessage = (event) => {
87+
* listener(event.data);
88+
* };
89+
* }
90+
* }
91+
* });
92+
*
93+
* // main.js
94+
* const worker = new Worker("worker.js");
95+
* const runtime = new SwiftRuntime({
96+
* threadChannel: {
97+
* postMessageToWorkerThread: (tid, data) => {
98+
* worker.postMessage(data);
99+
* },
100+
* listenMessageFromWorkerThread: (tid, listener) => {
101+
* worker.onmessage = (event) => {
102+
listener(event.data);
103+
* };
104+
* }
105+
* }
106+
* });
107+
* ```
108+
*/
109+
type SwiftRuntimeThreadChannel = {
110+
/**
111+
* This function is used to send messages from the worker thread to the main thread.
112+
* The message submitted by this function is expected to be listened by `listenMessageFromWorkerThread`.
113+
* @param message The message to be sent to the main thread.
114+
* @param transfer The array of objects to be transferred to the main thread.
115+
*/
116+
postMessageToMainThread: (message: WorkerToMainMessage, transfer: any[]) => void;
117+
/**
118+
* This function is expected to be set in the worker thread and should listen
119+
* to messages from the main thread sent by `postMessageToWorkerThread`.
120+
* @param listener The listener function to be called when a message is received from the main thread.
121+
*/
122+
listenMessageFromMainThread: (listener: (message: MainToWorkerMessage) => void) => void;
123+
} | {
124+
/**
125+
* This function is expected to be set in the main thread.
126+
* The message submitted by this function is expected to be listened by `listenMessageFromMainThread`.
127+
* @param tid The thread ID of the worker thread.
128+
* @param message The message to be sent to the worker thread.
129+
* @param transfer The array of objects to be transferred to the worker thread.
130+
*/
131+
postMessageToWorkerThread: (tid: number, message: MainToWorkerMessage, transfer: any[]) => void;
132+
/**
133+
* This function is expected to be set in the main thread and should listen
134+
* to messages sent by `postMessageToMainThread` from the worker thread.
135+
* @param tid The thread ID of the worker thread.
136+
* @param listener The listener function to be called when a message is received from the worker thread.
137+
*/
138+
listenMessageFromWorkerThread: (tid: number, listener: (message: WorkerToMainMessage) => void) => void;
139+
/**
140+
* This function is expected to be set in the main thread and called
141+
* when the worker thread is terminated.
142+
* @param tid The thread ID of the worker thread.
143+
*/
144+
terminateWorkerThread?: (tid: number) => void;
145+
};
146+
declare class ITCInterface {
147+
private memory;
148+
constructor(memory: Memory);
149+
send(sendingObject: ref, transferringObjects: ref[], sendingContext: pointer): {
150+
object: any;
151+
sendingContext: pointer;
152+
transfer: Transferable[];
153+
};
154+
sendObjects(sendingObjects: ref[], transferringObjects: ref[], sendingContext: pointer): {
155+
object: any[];
156+
sendingContext: pointer;
157+
transfer: Transferable[];
158+
};
159+
release(objectRef: ref): {
160+
object: undefined;
161+
transfer: Transferable[];
162+
};
163+
}
164+
type AllRequests<Interface extends Record<string, any>> = {
165+
[K in keyof Interface]: {
166+
method: K;
167+
parameters: Parameters<Interface[K]>;
168+
};
169+
};
170+
type ITCRequest<Interface extends Record<string, any>> = AllRequests<Interface>[keyof AllRequests<Interface>];
171+
type AllResponses<Interface extends Record<string, any>> = {
172+
[K in keyof Interface]: ReturnType<Interface[K]>;
173+
};
174+
type ITCResponse<Interface extends Record<string, any>> = AllResponses<Interface>[keyof AllResponses<Interface>];
175+
type RequestMessage = {
176+
type: "request";
177+
data: {
178+
/** The TID of the thread that sent the request */
179+
sourceTid: number;
180+
/** The TID of the thread that should respond to the request */
181+
targetTid: number;
182+
/** The context pointer of the request */
183+
context: pointer;
184+
/** The request content */
185+
request: ITCRequest<ITCInterface>;
186+
};
187+
};
188+
type SerializedError = {
189+
isError: true;
190+
value: Error;
191+
} | {
192+
isError: false;
193+
value: unknown;
194+
};
195+
type ResponseMessage = {
196+
type: "response";
197+
data: {
198+
/** The TID of the thread that sent the response */
199+
sourceTid: number;
200+
/** The context pointer of the request */
201+
context: pointer;
202+
/** The response content */
203+
response: {
204+
ok: true;
205+
value: ITCResponse<ITCInterface>;
206+
} | {
207+
ok: false;
208+
error: SerializedError;
209+
};
210+
};
211+
};
212+
type MainToWorkerMessage = {
213+
type: "wake";
214+
} | RequestMessage | ResponseMessage;
215+
type WorkerToMainMessage = {
216+
type: "job";
217+
data: number;
218+
} | RequestMessage | ResponseMessage;
219+
220+
type SwiftRuntimeOptions = {
221+
/**
222+
* If `true`, the memory space of the WebAssembly instance can be shared
223+
* between the main thread and the worker thread.
224+
*/
225+
sharedMemory?: boolean;
226+
/**
227+
* The thread channel is a set of functions that are used to communicate
228+
* between the main thread and the worker thread.
229+
*/
230+
threadChannel?: SwiftRuntimeThreadChannel;
231+
};
232+
declare class SwiftRuntime {
233+
private _instance;
234+
private _memory;
235+
private _closureDeallocator;
236+
private options;
237+
private version;
238+
private textDecoder;
239+
private textEncoder;
240+
/** The thread ID of the current thread. */
241+
private tid;
242+
constructor(options?: SwiftRuntimeOptions);
243+
setInstance(instance: WebAssembly.Instance): void;
244+
main(): void;
245+
/**
246+
* Start a new thread with the given `tid` and `startArg`, which
247+
* is forwarded to the `wasi_thread_start` function.
248+
* This function is expected to be called from the spawned Web Worker thread.
249+
*/
250+
startThread(tid: number, startArg: number): void;
251+
private get instance();
252+
private get exports();
253+
private get memory();
254+
private get closureDeallocator();
255+
private callHostFunction;
256+
/** @deprecated Use `wasmImports` instead */
257+
importObjects: () => ImportedFunctions;
258+
get wasmImports(): ImportedFunctions;
259+
private postMessageToMainThread;
260+
private postMessageToWorkerThread;
261+
}
262+
263+
export { SwiftRuntime };
264+
export type { SwiftRuntimeOptions };

0 commit comments

Comments
 (0)