Skip to content

Commit a3de6b0

Browse files
Refactoring heap object
1 parent b82f502 commit a3de6b0

File tree

1 file changed

+57
-48
lines changed

1 file changed

+57
-48
lines changed

src/web/src/index.ts

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@ enum JavaScriptValueKind {
2929
Function = 6,
3030
}
3131

32-
export class SwiftRuntime {
33-
private instance: WebAssembly.Instance | null;
32+
class SwiftRuntimeHeap {
3433
private _heapValues: Map<number, any>;
3534
private _heapNextKey: number;
3635

3736
constructor() {
38-
this.instance = null;
3937
let _global: any;
4038
if (typeof window !== "undefined") {
4139
_global = window
@@ -48,6 +46,41 @@ export class SwiftRuntime {
4846
this._heapNextKey = 1;
4947
}
5048

49+
allocHeap(value: any) {
50+
const isObject = typeof value == "object"
51+
if (isObject && value.swjs_heap_id) {
52+
return value.swjs_heap_id
53+
}
54+
const id = this._heapNextKey++;
55+
this._heapValues.set(id, value)
56+
if (isObject)
57+
Reflect.set(value, "swjs_heap_id", id);
58+
return id
59+
}
60+
61+
freeHeap(ref: ref) {
62+
const value = this._heapValues.get(ref);
63+
const isObject = typeof value == "object"
64+
if (isObject && value.swjs_heap_id) {
65+
delete value.swjs_heap_id;
66+
}
67+
this._heapValues.delete(ref)
68+
}
69+
70+
referenceHeap(ref: ref) {
71+
return this._heapValues.get(ref)
72+
}
73+
}
74+
75+
export class SwiftRuntime {
76+
private instance: WebAssembly.Instance | null;
77+
private heap: SwiftRuntimeHeap
78+
79+
constructor() {
80+
this.instance = null;
81+
this.heap = new SwiftRuntimeHeap();
82+
}
83+
5184
setInsance(instance: WebAssembly.Instance) {
5285
this.instance = instance
5386
}
@@ -59,30 +92,6 @@ export class SwiftRuntime {
5992
throw new Error("WebAssembly instance is not set yet");
6093
}
6194

62-
const allocHeap = (value: any) => {
63-
const isObject = typeof value == "object"
64-
if (isObject && value.swjs_heap_id) {
65-
return value.swjs_heap_id
66-
}
67-
const id = this._heapNextKey++;
68-
this._heapValues.set(id, value)
69-
if (isObject)
70-
Reflect.set(value, "swjs_heap_id", id);
71-
return id
72-
}
73-
74-
const freeHeap = (ref: ref) => {
75-
const value = this._heapValues.get(ref);
76-
const isObject = typeof value == "object"
77-
if (isObject && value.swjs_heap_id) {
78-
delete value.swjs_heap_id;
79-
}
80-
this._heapValues.delete(ref)
81-
}
82-
83-
const referenceHeap = (ref: ref) => {
84-
return this._heapValues.get(ref)
85-
}
8695

8796
const callHostFunction = (host_func_id: number, args: any[]) => {
8897
if (!this.instance)
@@ -99,7 +108,7 @@ export class SwiftRuntime {
99108
writeUint32(base + 8, value.payload2)
100109
}
101110
let output: any;
102-
const callback_func_ref = allocHeap(function(result: any) {
111+
const callback_func_ref = this.heap.allocHeap(function (result: any) {
103112
output = result
104113
})
105114
exports.swjs_call_host_function(host_func_id, argv, argc, callback_func_ref)
@@ -126,9 +135,9 @@ export class SwiftRuntime {
126135
const readUInt32 = (ptr: pointer) => {
127136
const uint8Memory = new Uint8Array(memory().buffer);
128137
return uint8Memory[ptr + 0]
129-
+ (uint8Memory[ptr + 1] << 8)
130-
+ (uint8Memory[ptr + 2] << 16)
131-
+ (uint8Memory[ptr + 3] << 24)
138+
+ (uint8Memory[ptr + 1] << 8)
139+
+ (uint8Memory[ptr + 2] << 16)
140+
+ (uint8Memory[ptr + 3] << 24)
132141
}
133142

134143
const writeUint32 = (ptr: pointer, value: number) => {
@@ -157,7 +166,7 @@ export class SwiftRuntime {
157166
return readString(payload1, payload2)
158167
}
159168
case JavaScriptValueKind.Object: {
160-
return referenceHeap(payload1)
169+
return this.heap.referenceHeap(payload1)
161170
}
162171
case JavaScriptValueKind.Null: {
163172
return null
@@ -166,7 +175,7 @@ export class SwiftRuntime {
166175
return undefined
167176
}
168177
case JavaScriptValueKind.Function: {
169-
return referenceHeap(payload1)
178+
return this.heap.referenceHeap(payload1)
170179
}
171180
default:
172181
throw new Error(`Type kind "${kind}" is not supported`)
@@ -199,7 +208,7 @@ export class SwiftRuntime {
199208
case "string": {
200209
return {
201210
kind: JavaScriptValueKind.String,
202-
payload1: allocHeap(value),
211+
payload1: this.heap.allocHeap(value),
203212
payload2: value.length,
204213
}
205214
}
@@ -213,14 +222,14 @@ export class SwiftRuntime {
213222
case "object": {
214223
return {
215224
kind: JavaScriptValueKind.Object,
216-
payload1: allocHeap(value),
225+
payload1: this.heap.allocHeap(value),
217226
payload2: 0,
218227
}
219228
}
220229
case "function": {
221230
return {
222231
kind: JavaScriptValueKind.Function,
223-
payload1: allocHeap(value),
232+
payload1: this.heap.allocHeap(value),
224233
payload2: 0,
225234
}
226235
}
@@ -250,15 +259,15 @@ export class SwiftRuntime {
250259
kind: JavaScriptValueKind,
251260
payload1: number, payload2: number
252261
) => {
253-
const obj = referenceHeap(ref);
262+
const obj = this.heap.referenceHeap(ref);
254263
Reflect.set(obj, readString(name, length), decodeValue(kind, payload1, payload2))
255264
},
256265
swjs_get_prop: (
257266
ref: ref, name: pointer, length: number,
258267
kind_ptr: pointer,
259268
payload1_ptr: pointer, payload2_ptr: pointer
260269
) => {
261-
const obj = referenceHeap(ref);
270+
const obj = this.heap.referenceHeap(ref);
262271
const result = Reflect.get(obj, readString(name, length));
263272
const { kind, payload1, payload2 } = encodeValue(result);
264273
writeUint32(kind_ptr, kind);
@@ -270,31 +279,31 @@ export class SwiftRuntime {
270279
kind: JavaScriptValueKind,
271280
payload1: number, payload2: number
272281
) => {
273-
const obj = referenceHeap(ref);
282+
const obj = this.heap.referenceHeap(ref);
274283
Reflect.set(obj, index, decodeValue(kind, payload1, payload2))
275284
},
276285
swjs_get_subscript: (
277286
ref: ref, index: number,
278287
kind_ptr: pointer,
279288
payload1_ptr: pointer, payload2_ptr: pointer
280289
) => {
281-
const obj = referenceHeap(ref);
290+
const obj = this.heap.referenceHeap(ref);
282291
const result = Reflect.get(obj, index);
283292
const { kind, payload1, payload2 } = encodeValue(result);
284293
writeUint32(kind_ptr, kind);
285294
writeUint32(payload1_ptr, payload1);
286295
writeUint32(payload2_ptr, payload2);
287296
},
288297
swjs_load_string: (ref: ref, buffer: pointer) => {
289-
const string = referenceHeap(ref);
298+
const string = this.heap.referenceHeap(ref);
290299
writeString(buffer, string);
291300
},
292301
swjs_call_function: (
293302
ref: ref, argv: pointer, argc: number,
294303
kind_ptr: pointer,
295304
payload1_ptr: pointer, payload2_ptr: pointer
296305
) => {
297-
const func = referenceHeap(ref)
306+
const func = this.heap.referenceHeap(ref)
298307
const result = Reflect.apply(func, undefined, decodeValues(argv, argc))
299308
const { kind, payload1, payload2 } = encodeValue(result);
300309
writeUint32(kind_ptr, kind);
@@ -307,8 +316,8 @@ export class SwiftRuntime {
307316
kind_ptr: pointer,
308317
payload1_ptr: pointer, payload2_ptr: pointer
309318
) => {
310-
const obj = referenceHeap(obj_ref)
311-
const func = referenceHeap(func_ref)
319+
const obj = this.heap.referenceHeap(obj_ref)
320+
const func = this.heap.referenceHeap(func_ref)
312321
const result = Reflect.apply(func, obj, decodeValues(argv, argc))
313322
const { kind, payload1, payload2 } = encodeValue(result);
314323
writeUint32(kind_ptr, kind);
@@ -319,7 +328,7 @@ export class SwiftRuntime {
319328
host_func_id: number,
320329
func_ref_ptr: pointer,
321330
) => {
322-
const func_ref = allocHeap(function() {
331+
const func_ref = this.heap.allocHeap(function () {
323332
return callHostFunction(host_func_id, Array.prototype.slice.call(arguments))
324333
})
325334
writeUint32(func_ref_ptr, func_ref)
@@ -328,14 +337,14 @@ export class SwiftRuntime {
328337
ref: ref, argv: pointer, argc: number,
329338
result_obj: pointer
330339
) => {
331-
const obj = referenceHeap(ref)
340+
const obj = this.heap.referenceHeap(ref)
332341
const result = Reflect.construct(obj, decodeValues(argv, argc))
333342
if (typeof result != "object")
334343
throw Error(`Invalid result type of object constructor of "${obj}": "${result}"`)
335-
writeUint32(result_obj, allocHeap(result));
344+
writeUint32(result_obj, this.heap.allocHeap(result));
336345
},
337346
swjs_destroy_ref: (ref: ref) => {
338-
freeHeap(ref)
347+
this.heap.freeHeap(ref)
339348
}
340349
}
341350
}

0 commit comments

Comments
 (0)