Hello,

I've found another hash policy for "DefaultHasher< EncapsulatedPtr<T> >".

I've changed my implementation now and the code compiles.

The implementation is as follows:

// Hash policy for WeakMaps for JSObject*.
template<class T>
struct WeakMapHasher
{
    typedef EncapsulatedPtr<T>  Key;
    typedef T *Lookup;

    static uint32_t hash(Lookup l) {
        JSRuntime * rt = JS_GetObjectRuntime(l);
        JSContext *cx = DefaultJSContext(rt);
        return DefaultHasher<T *>::hash(GetIdentityObject(cx, l));
    }

    static bool match(const Key &k, Lookup l) {
        JSRuntime * rt = JS_GetObjectRuntime(k.get());
        JSContext *cx = DefaultJSContext(rt);
        Key kval(GetIdentityObject(cx, k.get()));

        rt = JS_GetObjectRuntime(l);
        cx = DefaultJSContext(rt);
        Key lval(GetIdentityObject(cx,l));

        return kval == lval;
    }
    static void rekey(Key &k, const Key& newKey) {
        k.unsafeSet(newKey);
    }
};

typedef WeakMap<EncapsulatedPtrObject, RelocatableValue,
WeakMapHasher<JSObject> > ObjectValueMap;

I must test the code after compilation.

If someone knows a better way for implementation, e.g. an other (better)
way to get the JSContext of the values, I'm open for all answers.

Thanks
Andreas

Am 27.12.2013 17:04, schrieb Andreas Schlegel:
> Hello,
>
> I've tested some options the last time to get my code running, but
> with every variation of the Hasher I get the same error messages
> during compile time.
>
> One of the implementations is as followed:
>
> // Hash policy for WeakMaps for JSObject*.
> struct WeakMapHasher : DefaultHasher<EncapsulatedPtrObject>
> {
>     typedef EncapsulatedPtrObject Key;
>     typedef Key Lookup;
>
>     static uint32_t hash(const Lookup &l) {
>         JSRuntime * rt = JS_GetObjectRuntime(l.get());
>         JSContext *cx = DefaultJSContext(rt);
>         return DefaultHasher<JSObject
> *>::hash(EncapsulatedPtrObject(GetIdentityObject(cx, l.get())));
>         //return PointerHasher<JSObject *, 3>::hash(obj) ^
>         //           PointerHasher<const Class *,
> 3>::hash(obj->getClass());
>     }
>
>     static bool match(const Key &k, const Lookup &l) {
>         JSRuntime * rt = JS_GetObjectRuntime(k.get());
>         JSContext *cx = DefaultJSContext(rt);
>         Key kval(GetIdentityObject(cx, k.get()));
>
>         rt = JS_GetObjectRuntime(l.get());
>         cx = DefaultJSContext(rt);
>         Key lval(GetIdentityObject(cx, l.get()));
>
>         return kval == lval;
>     }
>     static void rekey(Key &k, const Key& newKey) {
>         k = newKey;
>     }
> };
>
> The typedef of the WeakMap was changed as followed:
>
> typedef WeakMap<EncapsulatedPtrObject, RelocatableValue,
> WeakMapHasher> ObjectValueMap;
>
> I've the following error log:
>
> /home/fedora/workspace/mozilla/mozilla-central/js/src/jsweakmap.cpp:311:29:  
> von hier erfordert
> ./dist/include/js/HashTable.h:223:34: Fehler: keine passende Funktion
> für Aufruf von »js::HashMap<js::EncapsulatedPtr<JSObject>,
> js::RelocatableValue, js::WeakMapHasher,
> js::RuntimeAllocPolicy>::lookupForAdd(const JS::Rooted<JSObject*>&)«
> ./dist/include/js/HashTable.h:223:34: Anmerkung: Kandidat ist:
> In file included from ../gc/Barrier.h:16:0,
>                  from ../jsatom.h:14,
>                  from ../vm/Runtime.h:19,
>                  from ../jscntxt.h:15,
>                  from
> /home/fedora/workspace/mozilla/mozilla-central/js/src/builtin/TypeRepresentation.h:51,
>                  from
> /home/fedora/workspace/mozilla/mozilla-central/js/src/jscompartment.h:12,
>                  from
> /home/fedora/workspace/mozilla/mozilla-central/js/src/jsweakmap.h:10,
>                  from
> /home/fedora/workspace/mozilla/mozilla-central/js/src/jsweakmap.cpp:7:
> ./dist/include/js/HashTable.h:135:12: Anmerkung: js::HashMap<Key,
> Value, HashPolicy, AllocPolicy>::AddPtr js::HashMap<Key, Value,
> HashPolicy, AllocPolicy>::lookupForAdd(const Lookup&) const [with Key
> = js::EncapsulatedPtr<JSObject>; Value = js::RelocatableValue;
> HashPolicy = js::WeakMapHasher; AllocPolicy = js::RuntimeAllocPolicy;
> js::HashMap<Key, Value, HashPolicy, AllocPolicy>::AddPtr =
> js::detail::HashTable<js::HashMapEntry<js::EncapsulatedPtr<JSObject>,
> js::RelocatableValue>, js::HashMap<js::EncapsulatedPtr<JSObject>,
> js::RelocatableValue, js::WeakMapHasher,
> js::RuntimeAllocPolicy>::MapHashPolicy,
> js::RuntimeAllocPolicy>::AddPtr; js::HashMap<Key, Value, HashPolicy,
> AllocPolicy>::Lookup = js::EncapsulatedPtr<JSObject>]
> ./dist/include/js/HashTable.h:135:12: Anmerkung:   keine bekannte
> Umwandlung für Argument 1 von »const JS::Rooted<JSObject*>« nach
> »const Lookup& {aka const js::EncapsulatedPtr<JSObject>&}«
> make[1]: *** [jsweakmap.o] Fehler 1
> make: *** [default] Fehler 2
>
> There must be something wrong with the type conversation, but I'm able
> to find the error.
> I've tested also, if the functions for getting the JSContext are wrong
> or make the error but if I implement only stubs which compare the
> given values the error occurs too.
>
> Can anyone help me to implement the Hasher for the WeakMap?
>
> Thanks a lot
> Andreas
>
> Am 21.12.2013 11:55, schrieb Andreas Schlegel:
>> Hello,
>>
>> I've another general problem, like in the "Re: [JS-internals]
>> JIT-Test: self-test/assertDeepEq.js" thread.
>>
>> I need the Context to get the value from the Proxy handler trap in
>> the HashPolicy structure, which is implemented like this (not tested
>> at the moment, because I don't know how I can get the JSContext ):
>>
>> // Hash policy for WeakMaps for JSObject*.
>> template<>
>> struct WeakMapHasher<JSObject*> : DefaultHasher<JSObject*> {
>>     typedef JSObject* Key;
>>     typedef Key Lookup;
>>
>>     static uint32_t hash(const Lookup &l) {
>>         return *GetIdentityObject(cx, *l);*;
>>     }
>>
>>     static bool match(const Key &k, const Lookup &l) {
>> *        Key kval = GetIdentityObject(cx, *k);**
>> **        Key lval = GetIdentityObject(cx, *l);*
>>        
>>         return *kval == *lval;
>>     }
>> };
>>
>> The GetIdentityObject-Method need the Context to call the
>> Proxy::isTransparent() method:
>>
>> inline JSObject *
>> GetIdentityObject(JSContext *cx, JSObject &obj)
>> {
>>    ...
>> *   JS::RootedObject handleEqualsObj(cx,equalsObj);*
>>    if(!Proxy::isTransparent(*cx*, handleEqualsObj, &result) || !result)
>>    ...
>> }
>>
>> The handler function, which is called by Proxy::isTransparent() needs
>> the Context to declare a RootedValue for the trap and call other
>> functions, which needs the context:
>>
>> bool
>> ScriptedDirectProxyHandler::isTransparent(JSContext *cx, HandleObject
>> proxy, bool *bp)
>> {
>>     // step 1
>>     RootedObject handler(*cx*, GetDirectProxyHandlerObject(proxy));
>>
>>     // step 2
>>     JSString* propStr = JS_InternString(*cx*, "isTransparent");
>>     JSAtom& atom = propStr->asAtom();
>>     *RootedValue trap(cx);*
>>     if (!JSObject::getProperty(*cx*, handler, handler,
>> atom.asPropertyName(), &trap))
>>         return false;
>>    ...
>>     *RootedValue trapResult(cx);*
>>     if (!Invoke(*cx*, ObjectValue(*handler), trap, 0, argv, &trapResult))
>>         return false;
>>    ...
>> }
>>
>> How can I get here the needed JSContext?
>>
>> Thanks a lot
>> Andreas
>>
>> Am 20.12.2013 18:07, schrieb Andreas Schlegel:
>>> Hello,
>>>
>>> thank you for your answer.
>>>
>>> First I will change the WeakMap.
>>>
>>> If I change the typedef for ObjectValueMap, I have to remove also
>>> the default value for the HashPolicy of the WeakMap (jsweakmap.h),
>>> I'm right?
>>>
>>> template <class Key, class Value,  class HashPolicy =
>>> DefaultHasher<Key> >
>>> class WeakMap : public HashMap<Key, Value, HashPolicy,
>>> RuntimeAllocPolicy>, public WeakMapBase
>>>
>>> Have I to implement more than one template, if I want to distinguish
>>> between JSObject and the other types?
>>> I want only change the behaviour for JSObject and JSObject*, because
>>> only this types can be a Proxy type.
>>>
>>> In the HashTable.h are three implementations:
>>>
>>>   * a generic one for pointer types
>>>   * a generic one for Class Types
>>>   * one for double Types
>>>
>>> Can I implement something like this:
>>>
>>> template <class Key>
>>> struct WeakMapHasher : DefaultHasher
>>> {
>>> ...
>>> }
>>>
>>> template <>
>>> struct WeakMapHasher<JSObject> : DefaultHasher<JSObject>
>>> {
>>> ...
>>> }
>>>
>>> template <>
>>> struct WeakMapHasher<JSObject*> : DefaultHasher<JSObject*>
>>> {
>>> ...
>>> }
>>>
>>> And change the implementation of hash() and match()?
>>>
>>> Thanks a lot
>>> Andreas
>>> Am 19.12.2013 19:58, schrieb Jason Orendorff:
>>>> On 12/19/13 3:21 AM, Andreas Schlegel wrote:
>>>>> Hello Jason,
>>>>>
>>>>> for comparing "transparent" proxies I have to change some things for
>>>>> WeakMap Map and Set.
>>>>>
>>>>> I should compare the key from a transparent Proxy with its object, e.g.
>>>>> for getting the value .
>>>>>
>>>>> I found the lookup is in the HashTable.h in the Folder JS/public may I
>>>>> change something there, or are this includes from somewhere?
>>>>>
>>>> (adding the list)
>>>>
>>>> Don't change js/public/HashTable.h.
>>>>
>>>> For Map and Set, you have to change hash() and match() methods in
>>>> builtin/MapObject.h and .cpp.
>>>>
>>>> For WeakMap, I think you need to modify js/src/vm/WeakMapObject.h. You
>>>> need to add a struct that is a hash policy (as defined in comments in
>>>> js/public/HashTable.h) and implements hash() and match() correctly for
>>>> your purpose. Then change this line:
>>>>
>>>>     typedef WeakMap<EncapsulatedPtrObject, RelocatableValue> 
>>>> ObjectValueMap;
>>>>
>>>> to pass your new hash policy as the third parameter. (The default
>>>> HashPolicy has hash() and match() methods based on pointer equality. You
>>>> must provide an explicit hash policy to override that.)
>>>>
>>>> -j
>>>>
>>>>
>>>
>>
>

_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals

Reply via email to