mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 01:35:35 +00:00
Bug 1121332. Part 3 - export MapObject from JS. r=jorendorff.
This commit is contained in:
parent
54a7b4ad6d
commit
35dfd3bbc3
@ -1305,11 +1305,24 @@ MapObject::is(HandleValue v)
|
||||
return v.isObject() && v.toObject().hasClass(&class_) && v.toObject().as<MapObject>().getPrivate();
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::is(HandleObject o)
|
||||
{
|
||||
return o->hasClass(&class_) && o->as<MapObject>().getPrivate();
|
||||
}
|
||||
|
||||
#define ARG0_KEY(cx, args, key) \
|
||||
AutoHashableValueRooter key(cx); \
|
||||
if (args.length() > 0 && !key.setValue(cx, args[0])) \
|
||||
return false
|
||||
|
||||
ValueMap &
|
||||
MapObject::extract(HandleObject o)
|
||||
{
|
||||
MOZ_ASSERT(o->hasClass(&MapObject::class_));
|
||||
return *o->as<MapObject>().getData();
|
||||
}
|
||||
|
||||
ValueMap &
|
||||
MapObject::extract(CallReceiver call)
|
||||
{
|
||||
@ -1318,15 +1331,21 @@ MapObject::extract(CallReceiver call)
|
||||
return *call.thisv().toObject().as<MapObject>().getData();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MapObject::size(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(obj));
|
||||
ValueMap &map = extract(obj);
|
||||
static_assert(sizeof(map.count()) <= sizeof(uint32_t),
|
||||
"map count must be precisely representable as a JS number");
|
||||
return map.count();
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::size_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(args.thisv()));
|
||||
|
||||
ValueMap &map = extract(args);
|
||||
static_assert(sizeof(map.count()) <= sizeof(uint32_t),
|
||||
"map count must be precisely representable as a JS number");
|
||||
args.rval().setNumber(map.count());
|
||||
RootedObject obj(cx, &args.thisv().toObject());
|
||||
args.rval().setNumber(size(cx, obj));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1337,19 +1356,31 @@ MapObject::size(JSContext *cx, unsigned argc, Value *vp)
|
||||
return CallNonGenericMethod<MapObject::is, MapObject::size_impl>(cx, args);
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::get(JSContext *cx, HandleObject obj,
|
||||
HandleValue key, MutableHandleValue rval)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(obj));
|
||||
|
||||
ValueMap &map = extract(obj);
|
||||
AutoHashableValueRooter k(cx);
|
||||
|
||||
if (!k.setValue(cx, key))
|
||||
return false;
|
||||
|
||||
if (ValueMap::Entry *p = map.get(k))
|
||||
rval.set(p->value);
|
||||
else
|
||||
rval.setUndefined();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::get_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(args.thisv()));
|
||||
|
||||
ValueMap &map = extract(args);
|
||||
ARG0_KEY(cx, args, key);
|
||||
|
||||
if (ValueMap::Entry *p = map.get(key))
|
||||
args.rval().set(p->value);
|
||||
else
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
RootedObject obj(cx, &args.thisv().toObject());
|
||||
return get(cx, obj, args.get(0), args.rval());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1359,15 +1390,31 @@ MapObject::get(JSContext *cx, unsigned argc, Value *vp)
|
||||
return CallNonGenericMethod<MapObject::is, MapObject::get_impl>(cx, args);
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::has(JSContext *cx, HandleObject obj, HandleValue key, bool *rval)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(obj));
|
||||
|
||||
ValueMap &map = extract(obj);
|
||||
AutoHashableValueRooter k(cx);
|
||||
|
||||
if (!k.setValue(cx, key))
|
||||
return false;
|
||||
|
||||
*rval = map.has(k);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::has_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(args.thisv()));
|
||||
|
||||
ValueMap &map = extract(args);
|
||||
ARG0_KEY(cx, args, key);
|
||||
args.rval().setBoolean(map.has(key));
|
||||
return true;
|
||||
bool found;
|
||||
RootedObject obj(cx, &args.thisv().toObject());
|
||||
if (has(cx, obj, args.get(0), &found)) {
|
||||
args.rval().setBoolean(found);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1433,16 +1480,21 @@ MapObject::delete_(JSContext *cx, unsigned argc, Value *vp)
|
||||
return CallNonGenericMethod<MapObject::is, MapObject::delete_impl>(cx, args);
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::iterator(JSContext *cx, IteratorKind kind,
|
||||
HandleObject obj, MutableHandleValue iter)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(obj));
|
||||
ValueMap &map = extract(obj);
|
||||
Rooted<JSObject*> iterobj(cx, MapIteratorObject::create(cx, obj, &map, kind));
|
||||
return iterobj && (iter.setObject(*iterobj), true);
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind)
|
||||
{
|
||||
Rooted<MapObject*> mapobj(cx, &args.thisv().toObject().as<MapObject>());
|
||||
ValueMap &map = *mapobj->getData();
|
||||
Rooted<JSObject*> iterobj(cx, MapIteratorObject::create(cx, mapobj, &map, kind));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
args.rval().setObject(*iterobj);
|
||||
return true;
|
||||
RootedObject obj(cx, &args.thisv().toObject());
|
||||
return iterator(cx, kind, obj, args.rval());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1487,13 +1539,9 @@ MapObject::entries(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
MapObject::clear_impl(JSContext *cx, CallArgs args)
|
||||
{
|
||||
Rooted<MapObject*> mapobj(cx, &args.thisv().toObject().as<MapObject>());
|
||||
if (!mapobj->getData()->clear()) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
RootedObject obj(cx, &args.thisv().toObject());
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
return clear(cx, obj);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1503,6 +1551,18 @@ MapObject::clear(JSContext *cx, unsigned argc, Value *vp)
|
||||
return CallNonGenericMethod(cx, is, clear_impl, args);
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::clear(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
MOZ_ASSERT(MapObject::is(obj));
|
||||
ValueMap &map = extract(obj);
|
||||
if (!map.clear()) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitMapClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
@ -2033,3 +2093,75 @@ js::InitSelfHostingCollectionIteratorFunctions(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return JS_DefineFunctions(cx, obj, selfhosting_collection_iterator_methods);
|
||||
}
|
||||
|
||||
/*** JS public APIs **********************************************************/
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS::NewMapObject(JSContext *cx)
|
||||
{
|
||||
return MapObject::create(cx);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(uint32_t)
|
||||
JS::MapSize(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return MapObject::size(cx, obj);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapGet(JSContext *cx, HandleObject obj,
|
||||
HandleValue key, MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, key, rval);
|
||||
return MapObject::get(cx, obj, key, rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, key);
|
||||
return MapObject::has(cx, obj, key, rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapSet(JSContext *cx, HandleObject obj,
|
||||
HandleValue key, HandleValue val)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, key, val);
|
||||
return MapObject::set(cx, obj, key, val);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapClear(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return MapObject::clear(cx, obj);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, rval);
|
||||
return MapObject::iterator(cx, MapObject::Keys, obj, rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapValues(JSContext *cx, HandleObject obj, MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, rval);
|
||||
return MapObject::iterator(cx, MapObject::Values, obj, rval);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::MapEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, rval);
|
||||
return MapObject::iterator(cx, MapObject::Entries, obj, rval);
|
||||
}
|
||||
|
@ -95,20 +95,28 @@ class MapObject : public NativeObject {
|
||||
static bool getKeysAndValuesInterleaved(JSContext *cx, HandleObject obj,
|
||||
JS::AutoValueVector *entries);
|
||||
static bool entries(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool set(JSContext *cx, HandleObject obj, HandleValue key, HandleValue value);
|
||||
static bool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static MapObject* create(JSContext *cx);
|
||||
|
||||
static uint32_t size(JSContext *cx, HandleObject obj);
|
||||
static bool get(JSContext *cx, HandleObject obj, HandleValue key, MutableHandleValue rval);
|
||||
static bool has(JSContext *cx, HandleObject obj, HandleValue key, bool* rval);
|
||||
static bool set(JSContext *cx, HandleObject obj, HandleValue key, HandleValue val);
|
||||
static bool clear(JSContext *cx, HandleObject obj);
|
||||
static bool iterator(JSContext *cx, IteratorKind kind, HandleObject obj, MutableHandleValue iter);
|
||||
|
||||
private:
|
||||
static const JSPropertySpec properties[];
|
||||
static const JSFunctionSpec methods[];
|
||||
ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); }
|
||||
static ValueMap & extract(HandleObject o);
|
||||
static ValueMap & extract(CallReceiver call);
|
||||
static void mark(JSTracer *trc, JSObject *obj);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
static bool construct(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
static bool is(HandleValue v);
|
||||
static bool is(HandleObject o);
|
||||
|
||||
static bool iterator_impl(JSContext *cx, CallArgs args, IteratorKind kind);
|
||||
|
||||
|
@ -4558,6 +4558,37 @@ extern JS_PUBLIC_API(bool)
|
||||
SetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
|
||||
JS::HandleValue val);
|
||||
|
||||
/*
|
||||
* Map
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
NewMapObject(JSContext *cx);
|
||||
|
||||
extern JS_PUBLIC_API(uint32_t)
|
||||
MapSize(JSContext *cx, HandleObject obj);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapGet(JSContext *cx, HandleObject obj,
|
||||
HandleValue key, MutableHandleValue rval);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapSet(JSContext *cx, HandleObject obj, HandleValue key, HandleValue val);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapClear(JSContext *cx, HandleObject obj);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapValues(JSContext *cx, HandleObject obj, MutableHandleValue rval);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
MapEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user