swiftwasm / JavaScriptKit

Swift framework to interact with JavaScript through WebAssembly.

Home Page:https://swiftpackageindex.com/swiftwasm/JavaScriptKit/main/documentation/javascriptkit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Making JSObject hashable

mhavu opened this issue · comments

Is there anything that would prevent using the object id for hashing in JSObject? Since hash values in Swift change between sessions anyway, I can't immediately see why using id would be a bad idea. All that would be needed to make JSObject conform to Hashable is to add:

public func hash(into hasher: inout Hasher) {
    hasher.combine(id)
}

Yeah, that could work, but we'd need to make id public to allow you adding this conformance in your code. I think you can just use ObjectIdentifier from stdlib in the meantime. Off the top of my head I can't come up with a scenario where one could have different JSObject instances that share the same id, but I may be wrong.

@swiftwasm/jskit-team WDYT about this approach? Does ObjectIdentifier seem safe enough to be used on JSObject for a custom Hashable conformance? Or should we just implement Hashable using id as the OP suggests?

Thanks for the tip! This seems to work just fine for now:

extension JSObject : Hashable {
    public func hash(into hasher: inout Hasher) {
        hasher.combine(ObjectIdentifier(self))
    }
}

Yeah, it may work in trivial scenarios, but until I'm 100% sure there's no way one can have multiple different JSObject instances with the same id, I hesitate to recommend that as a reliable solution. And maybe same can be said of id, but identity in JavaScript is defined much more loosely if at all.

When we do have that certainty, I guess it makes sense to add some Hashable conformance to our codebase, so that you don't have to keep this implementation in your code.

What exactly are you trying to achieve with it? Do you just want a dictionary or a set of JSObject keys/elements, or something more advanced than that?

I just need a dictionary with JSObject keys at the moment.

I think using id makes sense for hashing. SwiftRuntimeHeap.retain (on the JS side) checks whether the given object is already on the heap and reuses that heap entry (including the id) if possible. Therefore, JSObject.global.Array will return two different JSObject instances when called twice, but they will both have the same id.