Closed Bug 317485 Opened 19 years ago Closed 13 years ago

Implement getObjectId for js


(Core :: XPConnect, defect)

Windows XP
Not set





(Reporter: alex, Assigned: alex)




(1 file)

For zap we need a js mechanism of producing hash table keys for objects.
Patch coming up.
Attached patch patch v.1Splinter Review
This patch implements Components.utils.getObjectId(obj) which returns a unique identifier for obj, good for the lifetime of obj.
Attachment #203994 - Flags: review?(shaver)
Blocks: 317491
Comment on attachment 203994 [details] [diff] [review]
patch v.1

>+    JSObject *obj;
>+    if (!JS_ValueToObject(cx, argv[0], &obj))
>+        return NS_ERROR_FAILURE;
>+    jsid id;
>+    if (!JS_GetObjectId(cx, obj, &id))
>+        return NS_ERROR_FAILURE;

Do these not signal an exception?  I think they do, in which case
we should take care that callers see that exception, and not just
a generic NS_ERROR_FAILURE.  I don't recall whether or not you need
to return a special nsresult to signal that to XPConnect, but your
testing should show it clearly. =)

>+    char buf[80];
>+    sprintf(buf,"%p", id);
>+    JSString *str = JS_NewStringCopyZ(cx, buf);
>+    *retval = STRING_TO_JSVAL(str);

Better to use simply

  JS_IdToValue(cx, id, retval)

here and document that the id is a primitive.  If you really want
it to be a string, then JS_ValueToString afterwards will slake
your thirst.
Attachment #203994 - Flags: review?(shaver) → review-
QA Contact: pschwartau → xpconnect
Trying to unpick this (it's been a while since I did any SpiderMonkey development), I can't see any specific references to JS_ValueToObject signalling an exception. What's the definitive way to check? JS_GetPendingException? nsXPCWrappedJSClass::CheckForException looks like it has some related code, to convert the JSException to an XPCException and convert that to an nsresult, but it's, uh, quite a substantial chunk of code.

The JS_IdToValue path is better, I'll check with Alex how vital it is that we use a string.
JS_GetPendingException is the right way to check, as with all other JSAPI calls that can return JS_FALSE to signal failure.  We should make that clear in the JSAPI docs on MDC if we haven't already.

In the years since this bug was filed, I think ECMA TG1 has specified a similar method to live on Object.prototype proper; might be worth looking into that spec and just doing it for Spidermonkey.
ES4 will define a global function intrinsic::hashcode that computes a hash value for any other value. Since this function will be in the 'intrinsic' namespace, it would be good to implement Components.utils.getObjectId as an interim solution for gecko 1.9 (namespaces in JavaScript will only be implemented for Mozilla 2 I believe).
Blocks: abp
No longer blocks: abp
This is finally possible in JS, thanks to WeakMap (bug 547941).

var getObjectId = (function () {
    var nextId = 0;
    var map = new WeakMap;
    return function getObjectId(obj) {
        var i = map.get(obj);
        if (i === undefined) {
            i = nextId++;
            map.set(obj, i);
        return i;

Not that you would do this in order to produce hash codes; WeakMap is itself an identity hash table on object keys.
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.