1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/builtin/MapObject.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef builtin_MapObject_h 1.11 +#define builtin_MapObject_h 1.12 + 1.13 +#include "jsobj.h" 1.14 + 1.15 +#include "vm/Runtime.h" 1.16 + 1.17 +namespace js { 1.18 + 1.19 +/* 1.20 + * Comparing two ropes for equality can fail. The js::HashTable template 1.21 + * requires infallible hash() and match() operations. Therefore we require 1.22 + * all values to be converted to hashable form before being used as a key 1.23 + * in a Map or Set object. 1.24 + * 1.25 + * All values except ropes are hashable as-is. 1.26 + */ 1.27 +class HashableValue { 1.28 + EncapsulatedValue value; 1.29 + 1.30 + public: 1.31 + struct Hasher { 1.32 + typedef HashableValue Lookup; 1.33 + static HashNumber hash(const Lookup &v) { return v.hash(); } 1.34 + static bool match(const HashableValue &k, const Lookup &l) { return k == l; } 1.35 + static bool isEmpty(const HashableValue &v) { return v.value.isMagic(JS_HASH_KEY_EMPTY); } 1.36 + static void makeEmpty(HashableValue *vp) { vp->value = MagicValue(JS_HASH_KEY_EMPTY); } 1.37 + }; 1.38 + 1.39 + HashableValue() : value(UndefinedValue()) {} 1.40 + 1.41 + bool setValue(JSContext *cx, HandleValue v); 1.42 + HashNumber hash() const; 1.43 + bool operator==(const HashableValue &other) const; 1.44 + HashableValue mark(JSTracer *trc) const; 1.45 + Value get() const { return value.get(); } 1.46 +}; 1.47 + 1.48 +class AutoHashableValueRooter : private AutoGCRooter 1.49 +{ 1.50 + public: 1.51 + explicit AutoHashableValueRooter(JSContext *cx 1.52 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 1.53 + : AutoGCRooter(cx, HASHABLEVALUE) 1.54 + { 1.55 + MOZ_GUARD_OBJECT_NOTIFIER_INIT; 1.56 + } 1.57 + 1.58 + bool setValue(JSContext *cx, HandleValue v) { 1.59 + return value.setValue(cx, v); 1.60 + } 1.61 + 1.62 + operator const HashableValue & () { 1.63 + return value; 1.64 + } 1.65 + 1.66 + friend void AutoGCRooter::trace(JSTracer *trc); 1.67 + void trace(JSTracer *trc); 1.68 + 1.69 + private: 1.70 + HashableValue value; 1.71 + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 1.72 +}; 1.73 + 1.74 +template <class Key, class Value, class OrderedHashPolicy, class AllocPolicy> 1.75 +class OrderedHashMap; 1.76 + 1.77 +template <class T, class OrderedHashPolicy, class AllocPolicy> 1.78 +class OrderedHashSet; 1.79 + 1.80 +typedef OrderedHashMap<HashableValue, 1.81 + RelocatableValue, 1.82 + HashableValue::Hasher, 1.83 + RuntimeAllocPolicy> ValueMap; 1.84 + 1.85 +typedef OrderedHashSet<HashableValue, 1.86 + HashableValue::Hasher, 1.87 + RuntimeAllocPolicy> ValueSet; 1.88 + 1.89 +class MapObject : public JSObject { 1.90 + public: 1.91 + enum IteratorKind { Keys, Values, Entries }; 1.92 + 1.93 + static JSObject *initClass(JSContext *cx, JSObject *obj); 1.94 + static const Class class_; 1.95 + private: 1.96 + static const JSPropertySpec properties[]; 1.97 + static const JSFunctionSpec methods[]; 1.98 + ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); } 1.99 + static ValueMap & extract(CallReceiver call); 1.100 + static void mark(JSTracer *trc, JSObject *obj); 1.101 + static void finalize(FreeOp *fop, JSObject *obj); 1.102 + static bool construct(JSContext *cx, unsigned argc, Value *vp); 1.103 + 1.104 + static bool is(HandleValue v); 1.105 + 1.106 + static bool iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind); 1.107 + 1.108 + static bool size_impl(JSContext *cx, CallArgs args); 1.109 + static bool size(JSContext *cx, unsigned argc, Value *vp); 1.110 + static bool get_impl(JSContext *cx, CallArgs args); 1.111 + static bool get(JSContext *cx, unsigned argc, Value *vp); 1.112 + static bool has_impl(JSContext *cx, CallArgs args); 1.113 + static bool has(JSContext *cx, unsigned argc, Value *vp); 1.114 + static bool set_impl(JSContext *cx, CallArgs args); 1.115 + static bool set(JSContext *cx, unsigned argc, Value *vp); 1.116 + static bool delete_impl(JSContext *cx, CallArgs args); 1.117 + static bool delete_(JSContext *cx, unsigned argc, Value *vp); 1.118 + static bool keys_impl(JSContext *cx, CallArgs args); 1.119 + static bool keys(JSContext *cx, unsigned argc, Value *vp); 1.120 + static bool values_impl(JSContext *cx, CallArgs args); 1.121 + static bool values(JSContext *cx, unsigned argc, Value *vp); 1.122 + static bool entries_impl(JSContext *cx, CallArgs args); 1.123 + static bool entries(JSContext *cx, unsigned argc, Value *vp); 1.124 + static bool clear_impl(JSContext *cx, CallArgs args); 1.125 + static bool clear(JSContext *cx, unsigned argc, Value *vp); 1.126 +}; 1.127 + 1.128 +class SetObject : public JSObject { 1.129 + public: 1.130 + enum IteratorKind { Values, Entries }; 1.131 + static JSObject *initClass(JSContext *cx, JSObject *obj); 1.132 + static const Class class_; 1.133 + private: 1.134 + static const JSPropertySpec properties[]; 1.135 + static const JSFunctionSpec methods[]; 1.136 + ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); } 1.137 + static ValueSet & extract(CallReceiver call); 1.138 + static void mark(JSTracer *trc, JSObject *obj); 1.139 + static void finalize(FreeOp *fop, JSObject *obj); 1.140 + static bool construct(JSContext *cx, unsigned argc, Value *vp); 1.141 + 1.142 + static bool is(HandleValue v); 1.143 + 1.144 + static bool iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind); 1.145 + 1.146 + static bool size_impl(JSContext *cx, CallArgs args); 1.147 + static bool size(JSContext *cx, unsigned argc, Value *vp); 1.148 + static bool has_impl(JSContext *cx, CallArgs args); 1.149 + static bool has(JSContext *cx, unsigned argc, Value *vp); 1.150 + static bool add_impl(JSContext *cx, CallArgs args); 1.151 + static bool add(JSContext *cx, unsigned argc, Value *vp); 1.152 + static bool delete_impl(JSContext *cx, CallArgs args); 1.153 + static bool delete_(JSContext *cx, unsigned argc, Value *vp); 1.154 + static bool values_impl(JSContext *cx, CallArgs args); 1.155 + static bool values(JSContext *cx, unsigned argc, Value *vp); 1.156 + static bool entries_impl(JSContext *cx, CallArgs args); 1.157 + static bool entries(JSContext *cx, unsigned argc, Value *vp); 1.158 + static bool clear_impl(JSContext *cx, CallArgs args); 1.159 + static bool clear(JSContext *cx, unsigned argc, Value *vp); 1.160 +}; 1.161 + 1.162 +} /* namespace js */ 1.163 + 1.164 +extern JSObject * 1.165 +js_InitMapClass(JSContext *cx, js::HandleObject obj); 1.166 + 1.167 +extern JSObject * 1.168 +js_InitSetClass(JSContext *cx, js::HandleObject obj); 1.169 + 1.170 +#endif /* builtin_MapObject_h */