Hello,
is there any possibility to iterate through all entries of a WeakMap, or
to get all key objects of a weakmap for testing purposes from JavaScript?
Thanks a lot
Andreas
Am 27.12.2013 17:29, schrieb Andreas Schlegel:
> 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