1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef builtin_MapObject_h
8 #define builtin_MapObject_h
12 #include "vm/Runtime.h"
17 * Comparing two ropes for equality can fail. The js::HashTable template
18 * requires infallible hash() and match() operations. Therefore we require
19 * all values to be converted to hashable form before being used as a key
20 * in a Map or Set object.
22 * All values except ropes are hashable as-is.
25 PreBarrieredValue value
;
29 typedef HashableValue Lookup
;
30 static HashNumber
hash(const Lookup
& v
) { return v
.hash(); }
31 static bool match(const HashableValue
& k
, const Lookup
& l
) { return k
== l
; }
32 static bool isEmpty(const HashableValue
& v
) { return v
.value
.isMagic(JS_HASH_KEY_EMPTY
); }
33 static void makeEmpty(HashableValue
* vp
) { vp
->value
= MagicValue(JS_HASH_KEY_EMPTY
); }
36 HashableValue() : value(UndefinedValue()) {}
38 bool setValue(JSContext
* cx
, HandleValue v
);
39 HashNumber
hash() const;
40 bool operator==(const HashableValue
& other
) const;
41 HashableValue
mark(JSTracer
* trc
) const;
42 Value
get() const { return value
.get(); }
45 class AutoHashableValueRooter
: private JS::AutoGCRooter
48 explicit AutoHashableValueRooter(JSContext
* cx
49 MOZ_GUARD_OBJECT_NOTIFIER_PARAM
)
50 : JS::AutoGCRooter(cx
, HASHABLEVALUE
)
52 MOZ_GUARD_OBJECT_NOTIFIER_INIT
;
55 bool setValue(JSContext
* cx
, HandleValue v
) {
56 return value
.setValue(cx
, v
);
59 operator const HashableValue
& () {
63 Value
get() const { return value
.get(); }
65 friend void JS::AutoGCRooter::trace(JSTracer
* trc
);
66 void trace(JSTracer
* trc
);
70 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
73 template <class Key
, class Value
, class OrderedHashPolicy
, class AllocPolicy
>
76 template <class T
, class OrderedHashPolicy
, class AllocPolicy
>
79 typedef OrderedHashMap
<HashableValue
,
81 HashableValue::Hasher
,
82 RuntimeAllocPolicy
> ValueMap
;
84 typedef OrderedHashSet
<HashableValue
,
85 HashableValue::Hasher
,
86 RuntimeAllocPolicy
> ValueSet
;
88 class MapObject
: public NativeObject
{
90 enum IteratorKind
{ Keys
, Values
, Entries
};
92 static JSObject
* initClass(JSContext
* cx
, JSObject
* obj
);
93 static const Class class_
;
95 static bool getKeysAndValuesInterleaved(JSContext
* cx
, HandleObject obj
,
96 JS::AutoValueVector
* entries
);
97 static bool entries(JSContext
* cx
, unsigned argc
, Value
* vp
);
98 static bool has(JSContext
* cx
, unsigned argc
, Value
* vp
);
99 static MapObject
* create(JSContext
* cx
);
101 static uint32_t size(JSContext
* cx
, HandleObject obj
);
102 static bool get(JSContext
* cx
, HandleObject obj
, HandleValue key
, MutableHandleValue rval
);
103 static bool has(JSContext
* cx
, HandleObject obj
, HandleValue key
, bool* rval
);
104 static bool set(JSContext
* cx
, HandleObject obj
, HandleValue key
, HandleValue val
);
105 static bool clear(JSContext
* cx
, HandleObject obj
);
106 static bool iterator(JSContext
* cx
, IteratorKind kind
, HandleObject obj
, MutableHandleValue iter
);
109 static const JSPropertySpec properties
[];
110 static const JSFunctionSpec methods
[];
111 ValueMap
* getData() { return static_cast<ValueMap
*>(getPrivate()); }
112 static ValueMap
& extract(HandleObject o
);
113 static ValueMap
& extract(CallReceiver call
);
114 static void mark(JSTracer
* trc
, JSObject
* obj
);
115 static void finalize(FreeOp
* fop
, JSObject
* obj
);
116 static bool construct(JSContext
* cx
, unsigned argc
, Value
* vp
);
118 static bool is(HandleValue v
);
119 static bool is(HandleObject o
);
121 static bool iterator_impl(JSContext
* cx
, CallArgs args
, IteratorKind kind
);
123 static bool size_impl(JSContext
* cx
, CallArgs args
);
124 static bool size(JSContext
* cx
, unsigned argc
, Value
* vp
);
125 static bool get_impl(JSContext
* cx
, CallArgs args
);
126 static bool get(JSContext
* cx
, unsigned argc
, Value
* vp
);
127 static bool has_impl(JSContext
* cx
, CallArgs args
);
128 static bool set_impl(JSContext
* cx
, CallArgs args
);
129 static bool set(JSContext
* cx
, unsigned argc
, Value
* vp
);
130 static bool delete_impl(JSContext
* cx
, CallArgs args
);
131 static bool delete_(JSContext
* cx
, unsigned argc
, Value
* vp
);
132 static bool keys_impl(JSContext
* cx
, CallArgs args
);
133 static bool keys(JSContext
* cx
, unsigned argc
, Value
* vp
);
134 static bool values_impl(JSContext
* cx
, CallArgs args
);
135 static bool values(JSContext
* cx
, unsigned argc
, Value
* vp
);
136 static bool entries_impl(JSContext
* cx
, CallArgs args
);
137 static bool clear_impl(JSContext
* cx
, CallArgs args
);
138 static bool clear(JSContext
* cx
, unsigned argc
, Value
* vp
);
141 class SetObject
: public NativeObject
{
143 enum IteratorKind
{ Values
, Entries
};
144 static JSObject
* initClass(JSContext
* cx
, JSObject
* obj
);
145 static const Class class_
;
147 static bool keys(JSContext
* cx
, HandleObject obj
, JS::AutoValueVector
* keys
);
148 static bool values(JSContext
* cx
, unsigned argc
, Value
* vp
);
149 static bool add(JSContext
* cx
, HandleObject obj
, HandleValue key
);
150 static bool has(JSContext
* cx
, unsigned argc
, Value
* vp
);
151 static SetObject
* create(JSContext
* cx
);
154 static const JSPropertySpec properties
[];
155 static const JSFunctionSpec methods
[];
156 ValueSet
* getData() { return static_cast<ValueSet
*>(getPrivate()); }
157 static ValueSet
& extract(CallReceiver call
);
158 static void mark(JSTracer
* trc
, JSObject
* obj
);
159 static void finalize(FreeOp
* fop
, JSObject
* obj
);
160 static bool construct(JSContext
* cx
, unsigned argc
, Value
* vp
);
162 static bool is(HandleValue v
);
164 static bool iterator_impl(JSContext
* cx
, CallArgs args
, IteratorKind kind
);
166 static bool size_impl(JSContext
* cx
, CallArgs args
);
167 static bool size(JSContext
* cx
, unsigned argc
, Value
* vp
);
168 static bool has_impl(JSContext
* cx
, CallArgs args
);
169 static bool add_impl(JSContext
* cx
, CallArgs args
);
170 static bool add(JSContext
* cx
, unsigned argc
, Value
* vp
);
171 static bool delete_impl(JSContext
* cx
, CallArgs args
);
172 static bool delete_(JSContext
* cx
, unsigned argc
, Value
* vp
);
173 static bool values_impl(JSContext
* cx
, CallArgs args
);
174 static bool entries_impl(JSContext
* cx
, CallArgs args
);
175 static bool entries(JSContext
* cx
, unsigned argc
, Value
* vp
);
176 static bool clear_impl(JSContext
* cx
, CallArgs args
);
177 static bool clear(JSContext
* cx
, unsigned argc
, Value
* vp
);
181 InitSelfHostingCollectionIteratorFunctions(JSContext
* cx
, js::HandleObject obj
);
186 js_InitMapClass(JSContext
* cx
, js::HandleObject obj
);
189 js_InitSetClass(JSContext
* cx
, js::HandleObject obj
);
191 #endif /* builtin_MapObject_h */