зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset b6f1126059ef (bug 1198377) for asserting in for-in-iterator-1.js. r=backout
This commit is contained in:
Родитель
375da61c8b
Коммит
6fe4a47253
|
@ -2,53 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
|
||||
// 23.1.1.1 Map, steps 6-8
|
||||
function MapConstructorInit(iterable) {
|
||||
var map = this;
|
||||
|
||||
// Step 6.a.
|
||||
var adder = map.set;
|
||||
|
||||
// Step 6.b.
|
||||
if (!IsCallable(adder))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
|
||||
|
||||
// Step 6.c.
|
||||
var iterFn = iterable[std_iterator];
|
||||
if (!IsCallable(iterFn))
|
||||
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
|
||||
|
||||
var iter = callContentFunction(iterFn, iterable);
|
||||
if (!IsObject(iter))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
|
||||
|
||||
// Step 7 (not applicable).
|
||||
|
||||
// Step 8.
|
||||
while (true) {
|
||||
// Step 8.a.
|
||||
var next = callContentFunction(iter.next, iter);
|
||||
if (!IsObject(next))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
|
||||
|
||||
// Step 8.b.
|
||||
if (next.done)
|
||||
return;
|
||||
|
||||
// Step 8.c.
|
||||
var nextItem = next.value;
|
||||
|
||||
// Step 8.d.
|
||||
if (!IsObject(nextItem))
|
||||
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "Map");
|
||||
|
||||
// Steps 8.e-j.
|
||||
callContentFunction(adder, map, nextItem[0], nextItem[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ES6 20121122 draft 15.14.4.4. */
|
||||
|
||||
function MapForEach(callbackfn, thisArg = undefined) {
|
||||
/* Step 1-2. */
|
||||
var M = this;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "js/Utility.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
|
@ -501,12 +500,72 @@ MapObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
|
||||
if (!args.get(0).isNullOrUndefined()) {
|
||||
FixedInvokeArgs<1> args2(cx);
|
||||
args2[0].set(args[0]);
|
||||
|
||||
RootedValue thisv(cx, ObjectValue(*obj));
|
||||
if (!CallSelfHostedFunction(cx, cx->names().MapConstructorInit, thisv, args2, args2.rval()))
|
||||
RootedValue adderVal(cx);
|
||||
if (!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));
|
||||
FastCallGuard fig(cx, adderVal);
|
||||
InvokeArgs& args2 = fig.args();
|
||||
|
||||
ForOfIterator iter(cx);
|
||||
if (!iter.init(args[0]))
|
||||
return false;
|
||||
|
||||
RootedValue pairVal(cx);
|
||||
RootedObject pairObj(cx);
|
||||
RootedValue dummy(cx);
|
||||
Rooted<HashableValue> hkey(cx);
|
||||
ValueMap* map = obj->getData();
|
||||
while (true) {
|
||||
bool done;
|
||||
if (!iter.next(&pairVal, &done))
|
||||
return false;
|
||||
if (done)
|
||||
break;
|
||||
if (!pairVal.isObject()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INVALID_MAP_ITERABLE,
|
||||
"Map");
|
||||
return false;
|
||||
}
|
||||
|
||||
pairObj = &pairVal.toObject();
|
||||
if (!pairObj)
|
||||
return false;
|
||||
|
||||
RootedValue key(cx);
|
||||
if (!GetElement(cx, pairObj, pairObj, 0, &key))
|
||||
return false;
|
||||
|
||||
RootedValue val(cx);
|
||||
if (!GetElement(cx, pairObj, pairObj, 1, &val))
|
||||
return false;
|
||||
|
||||
if (isOriginalAdder) {
|
||||
if (!hkey.setValue(cx, key))
|
||||
return false;
|
||||
|
||||
HeapPtr<Value> rval(val);
|
||||
if (!map->put(hkey, rval)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
WriteBarrierPost(cx->runtime(), map, key);
|
||||
} else {
|
||||
if (!args2.init(2))
|
||||
return false;
|
||||
|
||||
args2[0].set(key);
|
||||
args2[1].set(val);
|
||||
|
||||
if (!fig.call(cx, adderVal, mapVal, &dummy))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
|
@ -1083,12 +1142,6 @@ SetObject::finalize(FreeOp* fop, JSObject* obj)
|
|||
fop->delete_(set);
|
||||
}
|
||||
|
||||
bool
|
||||
SetObject::isBuiltinAdd(HandleValue add, JSContext* cx)
|
||||
{
|
||||
return IsNativeFunction(add, SetObject::add);
|
||||
}
|
||||
|
||||
bool
|
||||
SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -1107,20 +1160,33 @@ SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
|
||||
if (!args.get(0).isNullOrUndefined()) {
|
||||
RootedValue iterable(cx, args[0]);
|
||||
bool optimized = false;
|
||||
if (!IsOptimizableInitForSet<GlobalObject::getOrCreateSetPrototype, isBuiltinAdd>(cx, obj, iterable, &optimized))
|
||||
RootedValue adderVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, cx->names().add, &adderVal))
|
||||
return false;
|
||||
|
||||
if (optimized) {
|
||||
RootedValue keyVal(cx);
|
||||
Rooted<HashableValue> key(cx);
|
||||
ValueSet* set = obj->getData();
|
||||
ArrayObject* array = &iterable.toObject().as<ArrayObject>();
|
||||
for (uint32_t index = 0; index < array->getDenseInitializedLength(); ++index) {
|
||||
keyVal.set(array->getDenseElement(index));
|
||||
MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE));
|
||||
if (!IsCallable(adderVal))
|
||||
return ReportIsNotFunction(cx, adderVal);
|
||||
|
||||
bool isOriginalAdder = IsNativeFunction(adderVal, SetObject::add);
|
||||
RootedValue setVal(cx, ObjectValue(*obj));
|
||||
FastCallGuard fig(cx, adderVal);
|
||||
InvokeArgs& args2 = fig.args();
|
||||
|
||||
RootedValue keyVal(cx);
|
||||
ForOfIterator iter(cx);
|
||||
if (!iter.init(args[0]))
|
||||
return false;
|
||||
Rooted<HashableValue> key(cx);
|
||||
RootedValue dummy(cx);
|
||||
ValueSet* set = obj->getData();
|
||||
while (true) {
|
||||
bool done;
|
||||
if (!iter.next(&keyVal, &done))
|
||||
return false;
|
||||
if (done)
|
||||
break;
|
||||
|
||||
if (isOriginalAdder) {
|
||||
if (!key.setValue(cx, keyVal))
|
||||
return false;
|
||||
if (!set->put(key)) {
|
||||
|
@ -1128,14 +1194,15 @@ SetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
}
|
||||
WriteBarrierPost(cx->runtime(), set, keyVal);
|
||||
}
|
||||
} else {
|
||||
FixedInvokeArgs<1> args2(cx);
|
||||
args2[0].set(args[0]);
|
||||
|
||||
RootedValue thisv(cx, ObjectValue(*obj));
|
||||
if (!CallSelfHostedFunction(cx, cx->names().SetConstructorInit, thisv, args2, args2.rval()))
|
||||
if (!args2.init(1))
|
||||
return false;
|
||||
|
||||
args2[0].set(keyVal);
|
||||
|
||||
if (!fig.call(cx, adderVal, setVal, &dummy))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "jsobj.h"
|
||||
|
||||
#include "builtin/SelfHostingDefines.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/PIC.h"
|
||||
#include "vm/Runtime.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -215,8 +213,6 @@ class SetObject : public NativeObject {
|
|||
static bool is(HandleValue v);
|
||||
static bool is(HandleObject o);
|
||||
|
||||
static bool isBuiltinAdd(HandleValue add, JSContext* cx);
|
||||
|
||||
static MOZ_MUST_USE bool iterator_impl(JSContext* cx, const CallArgs& args, IteratorKind kind);
|
||||
|
||||
static MOZ_MUST_USE bool size_impl(JSContext* cx, const CallArgs& args);
|
||||
|
@ -255,48 +251,6 @@ class SetIteratorObject : public NativeObject
|
|||
extern bool
|
||||
InitSelfHostingCollectionIteratorFunctions(JSContext* cx, js::HandleObject obj);
|
||||
|
||||
bool IsPackedArray(JSObject* obj);
|
||||
|
||||
using SetInitGetPrototypeOp = NativeObject* (*)(JSContext*, Handle<GlobalObject*>);
|
||||
using SetInitIsBuiltinOp = bool (*)(HandleValue, JSContext*);
|
||||
|
||||
template <SetInitGetPrototypeOp getPrototypeOp, SetInitIsBuiltinOp isBuiltinOp>
|
||||
static MOZ_MUST_USE bool
|
||||
IsOptimizableInitForSet(JSContext* cx, HandleObject setObject, HandleValue iterable, bool* optimized)
|
||||
{
|
||||
if (!iterable.isObject())
|
||||
return true;
|
||||
|
||||
RootedObject array(cx, &iterable.toObject());
|
||||
if (!IsPackedArray(array))
|
||||
return true;
|
||||
|
||||
// Get the canonical prototype object.
|
||||
RootedNativeObject setProto(cx, getPrototypeOp(cx, cx->global()));
|
||||
if (!setProto)
|
||||
return false;
|
||||
|
||||
// Ensures setObject's prototype is the canonical prototype.
|
||||
if (setObject->staticPrototype() != setProto)
|
||||
return true;
|
||||
|
||||
// Look up the 'add' value on the prototype object.
|
||||
Shape* addShape = setProto->lookup(cx, cx->names().add);
|
||||
if (!addShape || !addShape->hasSlot())
|
||||
return true;
|
||||
|
||||
// Get the referred value, ensure it holds the canonical add function.
|
||||
RootedValue add(cx, setProto->getSlot(addShape->slot()));
|
||||
if (!isBuiltinOp(add, cx))
|
||||
return true;
|
||||
|
||||
ForOfPIC::Chain* stubChain = ForOfPIC::getOrCreate(cx);
|
||||
if (!stubChain)
|
||||
return false;
|
||||
|
||||
return stubChain->tryOptimizeArray(cx, array.as<ArrayObject>(), optimized);
|
||||
}
|
||||
|
||||
extern JSObject*
|
||||
InitMapClass(JSContext* cx, HandleObject obj);
|
||||
|
||||
|
|
|
@ -2,49 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
|
||||
// 23.2.1.1 Set, steps 6-8
|
||||
function SetConstructorInit(iterable) {
|
||||
var set = this;
|
||||
|
||||
// Step 6.a.
|
||||
var adder = set.add;
|
||||
|
||||
// Step 6.b.
|
||||
if (!IsCallable(adder))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
|
||||
|
||||
// Step 6.c.
|
||||
var iterFn = iterable[std_iterator];
|
||||
if (!IsCallable(iterFn))
|
||||
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
|
||||
|
||||
var iter = callContentFunction(iterFn, iterable);
|
||||
if (!IsObject(iter))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
|
||||
|
||||
// Step 7 (not applicable).
|
||||
|
||||
// Step 8.
|
||||
while (true) {
|
||||
// Step 8.a.
|
||||
var next = callContentFunction(iter.next, iter);
|
||||
if (!IsObject(next))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
|
||||
|
||||
// Step 8.b.
|
||||
if (next.done)
|
||||
return;
|
||||
|
||||
// Step 8.c.
|
||||
var nextValue = next.value;
|
||||
|
||||
// Steps 8.d-e.
|
||||
callContentFunction(adder, set, nextValue);
|
||||
}
|
||||
}
|
||||
|
||||
/* ES6 20121122 draft 15.16.4.6. */
|
||||
|
||||
function SetForEach(callbackfn, thisArg = undefined) {
|
||||
/* Step 1-2. */
|
||||
var S = this;
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
|
||||
// 23.3.1.1 WeakMap, steps 6-8
|
||||
function WeakMapConstructorInit(iterable) {
|
||||
var map = this;
|
||||
|
||||
// Step 6.a.
|
||||
var adder = map.set;
|
||||
|
||||
// Step 6.b.
|
||||
if (!IsCallable(adder))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
|
||||
|
||||
// Step 6.c.
|
||||
var iterFn = iterable[std_iterator];
|
||||
if (!IsCallable(iterFn))
|
||||
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
|
||||
|
||||
var iter = callContentFunction(iterFn, iterable);
|
||||
if (!IsObject(iter))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
|
||||
|
||||
// Step 7 (not applicable).
|
||||
|
||||
// Step 8.
|
||||
while (true) {
|
||||
// Step 8.a.
|
||||
var next = callContentFunction(iter.next, iter);
|
||||
if (!IsObject(next))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
|
||||
|
||||
// Step 8.b.
|
||||
if (next.done)
|
||||
return;
|
||||
|
||||
// Step 8.c.
|
||||
var nextItem = next.value;
|
||||
|
||||
// Step 8.d.
|
||||
if (!IsObject(nextItem))
|
||||
ThrowTypeError(JSMSG_INVALID_MAP_ITERABLE, "WeakMap");
|
||||
|
||||
// Steps 8.e-j.
|
||||
callContentFunction(adder, map, nextItem[0], nextItem[1]);
|
||||
}
|
||||
}
|
|
@ -9,8 +9,6 @@
|
|||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "vm/SelfHosting.h"
|
||||
|
||||
#include "vm/Interpreter-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -302,12 +300,85 @@ WeakMap_construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
|
||||
// Steps 5-6, 11.
|
||||
if (!args.get(0).isNullOrUndefined()) {
|
||||
FixedInvokeArgs<1> args2(cx);
|
||||
args2[0].set(args[0]);
|
||||
|
||||
RootedValue thisv(cx, ObjectValue(*obj));
|
||||
if (!CallSelfHostedFunction(cx, cx->names().WeakMapConstructorInit, thisv, args2, args2.rval()))
|
||||
// Steps 7a-b.
|
||||
RootedValue adderVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, cx->names().set, &adderVal))
|
||||
return false;
|
||||
|
||||
// Step 7c.
|
||||
if (!IsCallable(adderVal))
|
||||
return ReportIsNotFunction(cx, adderVal);
|
||||
|
||||
bool isOriginalAdder = IsNativeFunction(adderVal, WeakMap_set);
|
||||
RootedValue mapVal(cx, ObjectValue(*obj));
|
||||
FastCallGuard fig(cx, adderVal);
|
||||
InvokeArgs& args2 = fig.args();
|
||||
|
||||
// Steps 7d-e.
|
||||
JS::ForOfIterator iter(cx);
|
||||
if (!iter.init(args[0]))
|
||||
return false;
|
||||
|
||||
RootedValue pairVal(cx);
|
||||
RootedObject pairObject(cx);
|
||||
RootedValue keyVal(cx);
|
||||
RootedObject keyObject(cx);
|
||||
RootedValue val(cx);
|
||||
RootedValue dummy(cx);
|
||||
while (true) {
|
||||
// Steps 12a-e.
|
||||
bool done;
|
||||
if (!iter.next(&pairVal, &done))
|
||||
return false;
|
||||
if (done)
|
||||
break;
|
||||
|
||||
// Step 12f.
|
||||
if (!pairVal.isObject()) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INVALID_MAP_ITERABLE,
|
||||
"WeakMap");
|
||||
return false;
|
||||
}
|
||||
|
||||
pairObject = &pairVal.toObject();
|
||||
if (!pairObject)
|
||||
return false;
|
||||
|
||||
// Steps 12g-h.
|
||||
if (!GetElement(cx, pairObject, pairObject, 0, &keyVal))
|
||||
return false;
|
||||
|
||||
// Steps 12i-j.
|
||||
if (!GetElement(cx, pairObject, pairObject, 1, &val))
|
||||
return false;
|
||||
|
||||
// Steps 12k-l.
|
||||
if (isOriginalAdder) {
|
||||
if (keyVal.isPrimitive()) {
|
||||
UniqueChars bytes =
|
||||
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, nullptr);
|
||||
if (!bytes)
|
||||
return false;
|
||||
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_NOT_NONNULL_OBJECT,
|
||||
bytes.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
keyObject = &keyVal.toObject();
|
||||
if (!SetWeakMapEntry(cx, obj, keyObject, val))
|
||||
return false;
|
||||
} else {
|
||||
if (!args2.init(2))
|
||||
return false;
|
||||
|
||||
args2[0].set(keyVal);
|
||||
args2[1].set(val);
|
||||
|
||||
if (!fig.call(cx, adderVal, mapVal, &dummy))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
|
|
|
@ -2,48 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// ES2017 draft rev 0e10c9f29fca1385980c08a7d5e7bb3eb775e2e4
|
||||
// 23.4.1.1 WeakSet, steps 6-8
|
||||
function WeakSetConstructorInit(iterable) {
|
||||
var set = this;
|
||||
|
||||
// Step 6.a.
|
||||
var adder = set.add;
|
||||
|
||||
// Step 6.b.
|
||||
if (!IsCallable(adder))
|
||||
ThrowTypeError(JSMSG_NOT_FUNCTION, typeof adder);
|
||||
|
||||
// Step 6.c.
|
||||
var iterFn = iterable[std_iterator];
|
||||
if (!IsCallable(iterFn))
|
||||
ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, iterable));
|
||||
|
||||
var iter = callContentFunction(iterFn, iterable);
|
||||
if (!IsObject(iter))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof iter);
|
||||
|
||||
// Step 7 (not applicable).
|
||||
|
||||
// Step 8.
|
||||
while (true) {
|
||||
// Step 8.a.
|
||||
var next = callContentFunction(iter.next, iter);
|
||||
if (!IsObject(next))
|
||||
ThrowTypeError(JSMSG_NOT_NONNULL_OBJECT, typeof next);
|
||||
|
||||
// Step 8.b.
|
||||
if (next.done)
|
||||
return;
|
||||
|
||||
// Step 8.c.
|
||||
var nextValue = next.value;
|
||||
|
||||
// Steps 8.d-e.
|
||||
callContentFunction(adder, set, nextValue);
|
||||
}
|
||||
}
|
||||
|
||||
// 23.4.3.1
|
||||
function WeakSet_add(value) {
|
||||
// Steps 1-3.
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "jscntxt.h"
|
||||
#include "jsiter.h"
|
||||
|
||||
#include "builtin/MapObject.h"
|
||||
#include "builtin/SelfHostingDefines.h"
|
||||
#include "builtin/WeakMapObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
|
@ -75,13 +74,6 @@ WeakSetObject::create(JSContext* cx, HandleObject proto /* = nullptr */)
|
|||
return obj;
|
||||
}
|
||||
|
||||
bool
|
||||
WeakSetObject::isBuiltinAdd(HandleValue add, JSContext* cx)
|
||||
{
|
||||
JSFunction* addFn;
|
||||
return IsFunctionObject(add, &addFn) && IsSelfHostedFunctionWithName(addFn, cx->names().WeakSet_add);
|
||||
}
|
||||
|
||||
bool
|
||||
WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -101,42 +93,61 @@ WeakSetObject::construct(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
|
||||
if (!args.get(0).isNullOrUndefined()) {
|
||||
RootedValue iterable(cx, args[0]);
|
||||
bool optimized = false;
|
||||
if (!IsOptimizableInitForSet<GlobalObject::getOrCreateWeakSetPrototype, isBuiltinAdd>(cx, obj, iterable, &optimized))
|
||||
RootedObject map(cx, &obj->getReservedSlot(WEAKSET_MAP_SLOT).toObject());
|
||||
|
||||
RootedValue adderVal(cx);
|
||||
if (!GetProperty(cx, obj, obj, cx->names().add, &adderVal))
|
||||
return false;
|
||||
|
||||
if (!IsCallable(adderVal))
|
||||
return ReportIsNotFunction(cx, adderVal);
|
||||
|
||||
JSFunction* adder;
|
||||
bool isOriginalAdder = IsFunctionObject(adderVal, &adder) &&
|
||||
IsSelfHostedFunctionWithName(adder, cx->names().WeakSet_add);
|
||||
RootedValue setVal(cx, ObjectValue(*obj));
|
||||
FastCallGuard fig(cx, adderVal);
|
||||
InvokeArgs& args2 = fig.args();
|
||||
|
||||
JS::ForOfIterator iter(cx);
|
||||
if (!iter.init(args[0]))
|
||||
return false;
|
||||
|
||||
if (optimized) {
|
||||
RootedValue keyVal(cx);
|
||||
RootedObject keyObject(cx);
|
||||
RootedValue dummy(cx);
|
||||
RootedValue placeholder(cx, BooleanValue(true));
|
||||
RootedObject map(cx, &obj->getReservedSlot(WEAKSET_MAP_SLOT).toObject());
|
||||
RootedArrayObject array(cx, &iterable.toObject().as<ArrayObject>());
|
||||
for (uint32_t index = 0; index < array->getDenseInitializedLength(); ++index) {
|
||||
keyVal.set(array->getDenseElement(index));
|
||||
MOZ_ASSERT(!keyVal.isMagic(JS_ELEMENTS_HOLE));
|
||||
while (true) {
|
||||
bool done;
|
||||
if (!iter.next(&keyVal, &done))
|
||||
return false;
|
||||
if (done)
|
||||
break;
|
||||
|
||||
if (isOriginalAdder) {
|
||||
if (keyVal.isPrimitive()) {
|
||||
UniqueChars bytes =
|
||||
DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, keyVal, nullptr);
|
||||
if (!bytes)
|
||||
return false;
|
||||
JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_NOT_NONNULL_OBJECT, bytes.get());
|
||||
JSMSG_NOT_NONNULL_OBJECT,
|
||||
bytes.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
keyObject = &keyVal.toObject();
|
||||
if (!SetWeakMapEntry(cx, map, keyObject, placeholder))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
FixedInvokeArgs<1> args2(cx);
|
||||
args2[0].set(args[0]);
|
||||
|
||||
RootedValue thisv(cx, ObjectValue(*obj));
|
||||
if (!CallSelfHostedFunction(cx, cx->names().WeakSetConstructorInit, thisv, args2, args2.rval()))
|
||||
if (!args2.init(1))
|
||||
return false;
|
||||
|
||||
args2[0].set(keyVal);
|
||||
|
||||
if (!fig.call(cx, adderVal, setVal, &dummy))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@ class WeakSetObject : public NativeObject
|
|||
|
||||
static WeakSetObject* create(JSContext* cx, HandleObject proto = nullptr);
|
||||
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
static bool isBuiltinAdd(HandleValue add, JSContext* cx);
|
||||
};
|
||||
|
||||
extern JSObject*
|
||||
|
|
|
@ -1578,20 +1578,14 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res)
|
|||
return true;
|
||||
|
||||
/* Don't handle getters, setters or calls from fun.call/fun.apply. */
|
||||
JSOp op = JSOp(*current);
|
||||
if (op != JSOP_CALL && op != JSOP_NEW)
|
||||
return true;
|
||||
|
||||
if (static_cast<unsigned>(formalIndex) >= GET_ARGC(current))
|
||||
if (JSOp(*current) != JSOP_CALL || static_cast<unsigned>(formalIndex) >= GET_ARGC(current))
|
||||
return true;
|
||||
|
||||
BytecodeParser parser(cx, script);
|
||||
if (!parser.parse())
|
||||
return false;
|
||||
|
||||
bool pushedNewTarget = op == JSOP_NEW;
|
||||
int formalStackIndex = parser.stackDepthAtPC(current) - GET_ARGC(current) - pushedNewTarget +
|
||||
formalIndex;
|
||||
int formalStackIndex = parser.stackDepthAtPC(current) - GET_ARGC(current) + formalIndex;
|
||||
MOZ_ASSERT(formalStackIndex >= 0);
|
||||
if (uint32_t(formalStackIndex) >= parser.stackDepthAtPC(current))
|
||||
return true;
|
||||
|
|
|
@ -767,7 +767,6 @@ selfhosted.inputs = [
|
|||
'builtin/Sorting.js',
|
||||
'builtin/TypedArray.js',
|
||||
'builtin/TypedObject.js',
|
||||
'builtin/WeakMap.js',
|
||||
'builtin/WeakSet.js'
|
||||
]
|
||||
|
||||
|
|
|
@ -181,7 +181,6 @@
|
|||
macro(locale, locale, "locale") \
|
||||
macro(lookupGetter, lookupGetter, "__lookupGetter__") \
|
||||
macro(lookupSetter, lookupSetter, "__lookupSetter__") \
|
||||
macro(MapConstructorInit, MapConstructorInit, "MapConstructorInit") \
|
||||
macro(MapIterator, MapIterator, "Map Iterator") \
|
||||
macro(maximumFractionDigits, maximumFractionDigits, "maximumFractionDigits") \
|
||||
macro(maximumSignificantDigits, maximumSignificantDigits, "maximumSignificantDigits") \
|
||||
|
@ -263,7 +262,6 @@
|
|||
macro(selfHosted, selfHosted, "self-hosted") \
|
||||
macro(sensitivity, sensitivity, "sensitivity") \
|
||||
macro(set, set, "set") \
|
||||
macro(SetConstructorInit, SetConstructorInit, "SetConstructorInit") \
|
||||
macro(SetIterator, SetIterator, "Set Iterator") \
|
||||
macro(setPrefix, setPrefix, "set ") \
|
||||
macro(setPrototypeOf, setPrototypeOf, "setPrototypeOf") \
|
||||
|
@ -328,8 +326,6 @@
|
|||
macro(void0, void0, "(void 0)") \
|
||||
macro(wasm, wasm, "wasm") \
|
||||
macro(watch, watch, "watch") \
|
||||
macro(WeakMapConstructorInit, WeakMapConstructorInit, "WeakMapConstructorInit") \
|
||||
macro(WeakSetConstructorInit, WeakSetConstructorInit, "WeakSetConstructorInit") \
|
||||
macro(WeakSet_add, WeakSet_add, "WeakSet_add") \
|
||||
macro(weekday, weekday, "weekday") \
|
||||
macro(weekendEnd, weekendEnd, "weekendEnd") \
|
||||
|
|
|
@ -427,18 +427,6 @@ class GlobalObject : public NativeObject
|
|||
return &global->getPrototype(key).toObject();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_Set))
|
||||
return nullptr;
|
||||
return &global->getPrototype(JSProto_Set).toObject().as<NativeObject>();
|
||||
}
|
||||
|
||||
static NativeObject* getOrCreateWeakSetPrototype(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_WeakSet))
|
||||
return nullptr;
|
||||
return &global->getPrototype(JSProto_WeakSet).toObject().as<NativeObject>();
|
||||
}
|
||||
|
||||
JSObject* getOrCreateIntlObject(JSContext* cx) {
|
||||
return getOrCreateObject(cx, APPLICATION_SLOTS + JSProto_Intl, initIntlObject);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче