Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,27 @@ Object_Conversion: do {
} catch {
print(error)
}

ObjectRef_Lifetime: do {
// ```js
// global.globalObject1 = {
// "prop_1": {
// "nested_prop": 1,
// },
// "prop_2": 2,
// "prop_3": true,
// "prop_4": [
// 3, 4, "str_elm_1", 5,
// ],
// ...
// }
// ```

let identity = JSClosure { $0[0] }
let ref1 = getJSValue(this: .global, name: "globalObject1").object!
let ref2 = identity(ref1).object!
try expectEqual(ref1.prop_2, .number(2))
try expectEqual(ref2.prop_2, .number(2))
} catch {
print(error)
}
21 changes: 20 additions & 1 deletion Sources/JavaScriptKit/JSObject.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import _CJavaScriptKit

private struct Weak<T: AnyObject> {
weak var ref: T?
}

private var cache = [UInt32: Weak<JSObjectRef>]()

@dynamicMemberLookup
public class JSObjectRef: Equatable {
internal var id: UInt32
init(id: UInt32) {
self.id = id
}

static func retrieve(id: UInt32) -> JSObjectRef {
if id != 0, let ref = cache[id]?.ref {
return ref
} else {
let ref = JSObjectRef(id: id)
cache[id] = Weak(ref: ref)
return ref
}
}

@_disfavoredOverload
public subscript(dynamicMember name: String) -> ((JSValueConvertible...) -> JSValue)? {
get {
Expand Down Expand Up @@ -46,7 +62,10 @@ public class JSObjectRef: Equatable {
static let _JS_Predef_Value_Global: UInt32 = 0
public static let global = JSObjectRef(id: _JS_Predef_Value_Global)

deinit { _destroy_ref(id) }
deinit {
cache[id] = nil
_destroy_ref(id)
}

public static func == (lhs: JSObjectRef, rhs: JSObjectRef) -> Bool {
return lhs.id == rhs.id
Expand Down
2 changes: 1 addition & 1 deletion Sources/JavaScriptKit/JSValueConvertible.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension RawJSValue: JSValueConvertible {
let string = String(decodingCString: UnsafePointer(buffer), as: UTF8.self)
return .string(string)
case JavaScriptValueKind_Object:
return .object(JSObjectRef(id: UInt32(payload1)))
return .object(JSObjectRef.retrieve(id: UInt32(payload1)))
case JavaScriptValueKind_Null:
return .null
case JavaScriptValueKind_Undefined:
Expand Down