Skip to content

Commit eab7eb8

Browse files
Manage object reference count in JS runtime
1 parent d670953 commit eab7eb8

File tree

3 files changed

+12
-24
lines changed

3 files changed

+12
-24
lines changed

Runtime/src/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,29 @@ class SwiftRuntimeHeap {
5050
allocHeap(value: any) {
5151
const isObject = typeof value == "object"
5252
if (isObject && value.swjs_heap_id) {
53+
value.swjs_heap_rc++;
5354
return value.swjs_heap_id
5455
}
5556
const id = this._heapNextKey++;
5657
this._heapValues.set(id, value)
57-
if (isObject)
58+
if (isObject) {
5859
Reflect.set(value, "swjs_heap_id", id);
60+
Reflect.set(value, "swjs_heap_rc", 1);
61+
}
5962
return id
6063
}
6164

6265
freeHeap(ref: ref) {
6366
const value = this._heapValues.get(ref);
6467
const isObject = typeof value == "object"
65-
if (isObject && value.swjs_heap_id) {
68+
if (isObject) {
69+
const rc = --value.swjs_heap_rc;
70+
if (rc != 0) return;
6671
delete value.swjs_heap_id;
72+
this._heapValues.delete(ref)
73+
} else {
74+
this._heapValues.delete(ref)
6775
}
68-
this._heapValues.delete(ref)
6976
}
7077

7178
referenceHeap(ref: ref) {

Sources/JavaScriptKit/JSObject.swift

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
import _CJavaScriptKit
22

3-
private struct Weak<T: AnyObject> {
4-
weak var ref: T?
5-
}
6-
7-
private var cache = [UInt32: Weak<JSObjectRef>]()
8-
93
@dynamicMemberLookup
104
public class JSObjectRef: Equatable {
115
internal var id: UInt32
126
init(id: UInt32) {
137
self.id = id
148
}
159

16-
static func retrieve(id: UInt32) -> JSObjectRef {
17-
if id != 0, let ref = cache[id]?.ref {
18-
return ref
19-
} else {
20-
let ref = JSObjectRef(id: id)
21-
cache[id] = Weak(ref: ref)
22-
return ref
23-
}
24-
}
25-
2610
@_disfavoredOverload
2711
public subscript(dynamicMember name: String) -> ((JSValueConvertible...) -> JSValue)? {
2812
get {
@@ -62,10 +46,7 @@ public class JSObjectRef: Equatable {
6246
static let _JS_Predef_Value_Global: UInt32 = 0
6347
public static let global = JSObjectRef(id: _JS_Predef_Value_Global)
6448

65-
deinit {
66-
cache[id] = nil
67-
_destroy_ref(id)
68-
}
49+
deinit { _destroy_ref(id) }
6950

7051
public static func == (lhs: JSObjectRef, rhs: JSObjectRef) -> Bool {
7152
return lhs.id == rhs.id

Sources/JavaScriptKit/JSValueConvertible.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ extension RawJSValue: JSValueConvertible {
111111
let string = String(decodingCString: UnsafePointer(buffer), as: UTF8.self)
112112
return .string(string)
113113
case JavaScriptValueKind_Object:
114-
return .object(JSObjectRef.retrieve(id: UInt32(payload1)))
114+
return .object(JSObjectRef(id: UInt32(payload1)))
115115
case JavaScriptValueKind_Null:
116116
return .null
117117
case JavaScriptValueKind_Undefined:

0 commit comments

Comments
 (0)