Bug 804279 - Part1: Support monkey-patched/overridden adder in Map constructor. r=evilpie

This commit is contained in:
Tooru Fujisawa 2014-12-01 17:02:15 +09:00
parent 5e858d2691
commit f9a5c904ef

View File

@ -1237,11 +1237,24 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.get(0).isNullOrUndefined()) {
RootedValue adderVal(cx);
if (!JSObject::getProperty(cx, obj, obj, cx->names().set, &adderVal))
return false;
if (!IsCallable(adderVal))
return ReportIsNotFunction(cx, adderVal);
bool isOriginalAdder = IsNativeFunction(adderVal, MapObject::set);
RootedValue mapVal(cx, ObjectValue(*obj));
FastInvokeGuard fig(cx, adderVal);
InvokeArgs &args2 = fig.args();
ForOfIterator iter(cx);
if (!iter.init(args[0]))
return false;
RootedValue pairVal(cx);
RootedObject pairObj(cx);
AutoHashableValueRooter hkey(cx);
ValueMap *map = obj->getData();
while (true) {
bool done;
@ -1263,20 +1276,32 @@ MapObject::construct(JSContext *cx, unsigned argc, Value *vp)
if (!JSObject::getElement(cx, pairObj, pairObj, 0, &key))
return false;
AutoHashableValueRooter hkey(cx);
if (!hkey.setValue(cx, key))
return false;
RootedValue val(cx);
if (!JSObject::getElement(cx, pairObj, pairObj, 1, &val))
return false;
RelocatableValue rval(val);
if (!map->put(hkey, rval)) {
js_ReportOutOfMemory(cx);
return false;
if (isOriginalAdder) {
if (!hkey.setValue(cx, key))
return false;
RelocatableValue rval(val);
if (!map->put(hkey, rval)) {
js_ReportOutOfMemory(cx);
return false;
}
WriteBarrierPost(cx->runtime(), map, key);
} else {
if (!args2.init(2))
return false;
args2.setCallee(adderVal);
args2.setThis(mapVal);
args2[0].set(key);
args2[1].set(val);
if (!fig.invoke(cx))
return false;
}
WriteBarrierPost(cx->runtime(), map, key);
}
}