mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Backed out 4 changesets (bug 1098412) for failing browser_webconsole_bug_632347_iterators_generators.js
Backed out changeset f4da55f291cb (bug 1098412) Backed out changeset e9a0298824d6 (bug 1098412) Backed out changeset 8281805e7c3c (bug 1098412) Backed out changeset 1643079d7661 (bug 1098412) MozReview-Commit-ID: 5kuHtUjx1UM
This commit is contained in:
parent
d8022d7f17
commit
fd6ec799b2
@ -47,6 +47,7 @@ var ecmaGlobals =
|
||||
"Int8Array",
|
||||
"InternalError",
|
||||
"Intl",
|
||||
"Iterator",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
|
@ -42,6 +42,7 @@ var ecmaGlobals =
|
||||
"Int8Array",
|
||||
"InternalError",
|
||||
"Intl",
|
||||
"Iterator",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
|
@ -42,6 +42,7 @@ var ecmaGlobals =
|
||||
"Int8Array",
|
||||
"InternalError",
|
||||
"Intl",
|
||||
"Iterator",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "jscntxt.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsprf.h"
|
||||
#include "jswrapper.h"
|
||||
@ -4429,17 +4428,6 @@ IsConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsLegacyIterator(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() < 1)
|
||||
args.rval().setBoolean(false);
|
||||
else
|
||||
args.rval().setBoolean(IsLegacyIterator(args[0]));
|
||||
return true;
|
||||
}
|
||||
|
||||
static const JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
JS_FN_HELP("gc", ::GC, 0, 0,
|
||||
"gc([obj] | 'zone' [, 'shrinking'])",
|
||||
@ -5031,10 +5019,6 @@ gc::ZealModeHelpText),
|
||||
"isConstructor(value)",
|
||||
" Returns whether the value is considered IsConstructor.\n"),
|
||||
|
||||
JS_FN_HELP("isLegacyIterator", IsLegacyIterator, 1, 0,
|
||||
"isLegacyIterator(value)",
|
||||
" Returns whether the value is considered is a legacy iterator.\n"),
|
||||
|
||||
JS_FS_HELP_END
|
||||
};
|
||||
|
||||
|
7
js/src/jit-test/tests/auto-regress/bug1343245.js
Normal file
7
js/src/jit-test/tests/auto-regress/bug1343245.js
Normal file
@ -0,0 +1,7 @@
|
||||
// |jit-test| error:TypeError
|
||||
var o = {
|
||||
__iterator__: function() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
for (var j in o) {}
|
8
js/src/jit-test/tests/auto-regress/bug511836.js
Normal file
8
js/src/jit-test/tests/auto-regress/bug511836.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Binary: cache/js-dbg-32-16baceea5fe2-linux
|
||||
// Flags:
|
||||
//
|
||||
for (a in (function () {
|
||||
return Iterator(function () {}).__proto__
|
||||
})()) {
|
||||
++b
|
||||
}
|
9
js/src/jit-test/tests/auto-regress/bug561278.js
Normal file
9
js/src/jit-test/tests/auto-regress/bug561278.js
Normal file
@ -0,0 +1,9 @@
|
||||
// Binary: cache/js-dbg-32-fe937d72a9ce-linux
|
||||
// Flags:
|
||||
//
|
||||
x = Iterator([])
|
||||
for (z in x) {}
|
||||
(function() {
|
||||
for (l in function() {}) {}
|
||||
} ())
|
||||
for (z in x) {}
|
6
js/src/jit-test/tests/auto-regress/bug617485.js
Normal file
6
js/src/jit-test/tests/auto-regress/bug617485.js
Normal file
@ -0,0 +1,6 @@
|
||||
// |jit-test| error:SyntaxError
|
||||
|
||||
// Binary: cache/js-dbg-64-4c1fbfcf1d0d-linux
|
||||
// Flags:
|
||||
//
|
||||
Iterator(evalcx('#2=*'))
|
13
js/src/jit-test/tests/auto-regress/bug637010.js
Normal file
13
js/src/jit-test/tests/auto-regress/bug637010.js
Normal file
@ -0,0 +1,13 @@
|
||||
// Binary: cache/js-dbg-64-d708c2fa7fea-linux
|
||||
// Flags:
|
||||
//
|
||||
var o0 = Iterator.prototype;
|
||||
function f0(o) {}
|
||||
try {
|
||||
for(var i=0; i<7; i++) {
|
||||
try { o0.prototype(); } catch(e) {
|
||||
if (o0.next() != 7)
|
||||
throw "7 not yielded";
|
||||
};
|
||||
}
|
||||
} catch(exc1) {}
|
7
js/src/jit-test/tests/auto-regress/bug778557.js
Normal file
7
js/src/jit-test/tests/auto-regress/bug778557.js
Normal file
@ -0,0 +1,7 @@
|
||||
// Binary: cache/js-dbg-64-90828ac18dcf-linux
|
||||
// Flags:
|
||||
//
|
||||
x = Set;
|
||||
eval("function y() { return Iterator; }", this);
|
||||
x.__iterator__ = y;
|
||||
new Iterator(x)
|
13
js/src/jit-test/tests/baseline/bug1153458.js
Normal file
13
js/src/jit-test/tests/baseline/bug1153458.js
Normal file
@ -0,0 +1,13 @@
|
||||
// |jit-test| --baseline-eager; error: TypeError
|
||||
try {
|
||||
this.__defineGetter__("x", Iterator)()
|
||||
} catch (e) {}
|
||||
f = function() {
|
||||
return (function() {
|
||||
this.x
|
||||
})
|
||||
}()
|
||||
try {
|
||||
f()
|
||||
} catch (e) {}
|
||||
f()
|
27
js/src/jit-test/tests/basic/bug649939.js
Normal file
27
js/src/jit-test/tests/basic/bug649939.js
Normal file
@ -0,0 +1,27 @@
|
||||
// This was the actual bug
|
||||
assertRaises(StopIteration, function() {
|
||||
Iterator.prototype.next();
|
||||
Iterator.prototype.next();
|
||||
});
|
||||
|
||||
// The error should have triggered here, but was masked by a latent bug
|
||||
assertRaises(StopIteration, function() {
|
||||
Iterator.prototype.next();
|
||||
});
|
||||
|
||||
// Found by fuzzing
|
||||
assertRaises(StopIteration, function() {
|
||||
(new Iterator({})).__proto__.next();
|
||||
});
|
||||
|
||||
|
||||
function assertRaises(exc, callback) {
|
||||
var caught = false;
|
||||
try {
|
||||
callback();
|
||||
} catch (e) {
|
||||
assertEq(e instanceof StopIteration, true);
|
||||
caught = true;
|
||||
}
|
||||
assertEq(caught, true);
|
||||
}
|
6
js/src/jit-test/tests/basic/bug684922.js
Normal file
6
js/src/jit-test/tests/basic/bug684922.js
Normal file
@ -0,0 +1,6 @@
|
||||
// |jit-test| error: InternalError
|
||||
var op = Object.prototype;
|
||||
op.b = op;
|
||||
op.__iterator__ = Iterator;
|
||||
for (var c in {}) {}
|
||||
|
9
js/src/jit-test/tests/basic/bug885648.js
Normal file
9
js/src/jit-test/tests/basic/bug885648.js
Normal file
@ -0,0 +1,9 @@
|
||||
gczeal(4,1);
|
||||
var iterable = {persistedProp: 17};
|
||||
iterable.__iterator__ = function() {
|
||||
yield ["foo", 2];
|
||||
yield ["bar", 3];
|
||||
};
|
||||
var it = Iterator(iterable);
|
||||
assertEq(it.next().toString(), "foo,2");
|
||||
assertEq(it.next().toString(), "bar,3");
|
@ -65,6 +65,7 @@ test("new Number(1)", n => Number.prototype.valueOf.call(n));
|
||||
test("new Number(1)", n => Number.prototype.toFixed.call(n));
|
||||
test("new Number(1)", n => Number.prototype.toExponential.call(n));
|
||||
test("new Number(1)", n => Number.prototype.toPrecision.call(n));
|
||||
test("new Iterator({x:1})", i => Iterator.prototype.next.call(i).toString());
|
||||
test("(function(){yield 1})()", i => (function(){yield})().next.call(i).toString());
|
||||
test("new String('one')", s => String.prototype.toSource.call(s));
|
||||
test("new String('one')", s => String.prototype.toString.call(s));
|
||||
|
26
js/src/jit-test/tests/basic/testCustomIterator.js
Normal file
26
js/src/jit-test/tests/basic/testCustomIterator.js
Normal file
@ -0,0 +1,26 @@
|
||||
function my_iterator_next() {
|
||||
if (this.i == 10) {
|
||||
this.i = 0;
|
||||
throw this.StopIteration;
|
||||
}
|
||||
return this.i++;
|
||||
}
|
||||
function testCustomIterator() {
|
||||
var o = {
|
||||
__iterator__: function () {
|
||||
return {
|
||||
i: 0,
|
||||
next: my_iterator_next,
|
||||
StopIteration: StopIteration
|
||||
};
|
||||
}
|
||||
};
|
||||
var a=[];
|
||||
for (var k = 0; k < 100; k += 10) {
|
||||
for(var j in o) {
|
||||
a[k + (j >> 0)] = j*k;
|
||||
}
|
||||
}
|
||||
return a.join();
|
||||
}
|
||||
assertEq(testCustomIterator(), "0,0,0,0,0,0,0,0,0,0,0,10,20,30,40,50,60,70,80,90,0,20,40,60,80,100,120,140,160,180,0,30,60,90,120,150,180,210,240,270,0,40,80,120,160,200,240,280,320,360,0,50,100,150,200,250,300,350,400,450,0,60,120,180,240,300,360,420,480,540,0,70,140,210,280,350,420,490,560,630,0,80,160,240,320,400,480,560,640,720,0,90,180,270,360,450,540,630,720,810");
|
@ -5,6 +5,7 @@ load(libdir + "iteration.js");
|
||||
function test(obj, name) {
|
||||
var iter = obj[Symbol.iterator]();
|
||||
assertEq(typeof iter, "object");
|
||||
assertEq(iter instanceof Iterator, false); // Not a legacy Iterator.
|
||||
assertEq(iter.toString(), "[object " + obj.constructor.name + " Iterator]");
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,14 @@ check("x << 1");
|
||||
check("x >> 1");
|
||||
check("x >>> 1");
|
||||
|
||||
g.eval("function lastStep() { throw StopIteration; }");
|
||||
g.eval("function emptyIterator() { debugger; log += 'x'; return { next: lastStep }; }");
|
||||
g.eval("var customEmptyIterator = { __iterator__: emptyIterator };");
|
||||
g.log = '';
|
||||
g.eval("for (i in customEmptyIterator);\n" +
|
||||
"log += 'y';\n");
|
||||
assertEq(g.log, 'dxsy');
|
||||
|
||||
g.eval("var getter = { get x() { debugger; return log += 'x'; } }");
|
||||
check("getter.x");
|
||||
|
||||
|
5
js/src/jit-test/tests/for-of/next-1.js
Normal file
5
js/src/jit-test/tests/for-of/next-1.js
Normal file
@ -0,0 +1,5 @@
|
||||
// Iterator.prototype.next throws if applied to a value that isn't an iterator.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
for (var v of [null, undefined, false, 0, "ponies", {}, [], this])
|
||||
assertThrowsInstanceOf(function () { Iterator.prototype.next.call(v); }, TypeError);
|
8
js/src/jit-test/tests/for-of/next-2.js
Normal file
8
js/src/jit-test/tests/for-of/next-2.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Iterator.prototype.next throws if applied to a non-iterator that inherits from an iterator.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
load(libdir + "iteration.js");
|
||||
|
||||
var it = [1, 2][Symbol.iterator]();
|
||||
var v = Object.create(it);
|
||||
assertThrowsInstanceOf(function () { Iterator.prototype.next.call(v); }, TypeError);
|
7
js/src/jit-test/tests/for-of/next-surfaces.js
Normal file
7
js/src/jit-test/tests/for-of/next-surfaces.js
Normal file
@ -0,0 +1,7 @@
|
||||
// Test superficial features of the Iterator.prototype.next builtin function.
|
||||
|
||||
assertEq(Iterator.prototype.next.length, 0);
|
||||
var desc = Object.getOwnPropertyDescriptor(Iterator.prototype, "next");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.writable, true);
|
11
js/src/jit-test/tests/ion/bug735869.js
Normal file
11
js/src/jit-test/tests/ion/bug735869.js
Normal file
@ -0,0 +1,11 @@
|
||||
o = {}
|
||||
for (let i = 0; i < 70; i++) {
|
||||
try {
|
||||
p
|
||||
} catch (e) {}
|
||||
(function() {
|
||||
for (x in Iterator.prototype) {}
|
||||
})()
|
||||
o.__proto__ = null
|
||||
delete o.__proto__
|
||||
}
|
8
js/src/jit-test/tests/ion/bug754718.js
Normal file
8
js/src/jit-test/tests/ion/bug754718.js
Normal file
@ -0,0 +1,8 @@
|
||||
// |jit-test| error: TypeError; need-for-each
|
||||
|
||||
(function() {
|
||||
var a, b;
|
||||
for each (a in [{}, {__iterator__: function(){}}])
|
||||
for (b in a) { }
|
||||
})();
|
||||
|
12
js/src/jit-test/tests/ion/bug852174.js
Normal file
12
js/src/jit-test/tests/ion/bug852174.js
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
function eval() {
|
||||
return isPrototypeOf[Iterator.length];
|
||||
}
|
||||
function DoWhile_3() {
|
||||
return eval();
|
||||
}
|
||||
DoWhile_3();
|
||||
function f() {
|
||||
return DoWhile_3(f - 0);
|
||||
}
|
||||
for (var i in f());
|
7
js/src/jit-test/tests/jaeger/bug554580-1.js
Normal file
7
js/src/jit-test/tests/jaeger/bug554580-1.js
Normal file
@ -0,0 +1,7 @@
|
||||
// |jit-test| error: TypeError
|
||||
for (var a = 0; a < 7; ++a) {
|
||||
if (a == 1) {
|
||||
Iterator()
|
||||
}
|
||||
}
|
||||
|
12
js/src/jit-test/tests/jaeger/recompile/bug671943-1.js
Normal file
12
js/src/jit-test/tests/jaeger/recompile/bug671943-1.js
Normal file
@ -0,0 +1,12 @@
|
||||
gczeal(2);
|
||||
o1 = Iterator;
|
||||
var o2 = (function() { return arguments; })();
|
||||
function f(o) {
|
||||
for(var j=0; j<20; j++) {
|
||||
Object.seal(o2);
|
||||
(function() { return eval(o); })() == o1;
|
||||
(function() { return {x: arguments}.x; })();
|
||||
if (false) {};
|
||||
}
|
||||
}
|
||||
f({});
|
@ -341,9 +341,13 @@ CallJSNativeConstructor(JSContext* cx, Native native, const CallArgs& args)
|
||||
* - CallOrConstructBoundFunction is an exception as well because we might
|
||||
* have used bind on a proxy function.
|
||||
*
|
||||
* - new Iterator(x) is user-hookable; it returns x.__iterator__() which
|
||||
* could be any object.
|
||||
*
|
||||
* - (new Object(Object)) returns the callee.
|
||||
*/
|
||||
MOZ_ASSERT_IF(native != js::proxy_Construct &&
|
||||
native != js::IteratorConstructor &&
|
||||
(!callee->is<JSFunction>() || callee->as<JSFunction>().native() != obj_construct),
|
||||
args.rval().isObject() && callee != &args.rval().toObject());
|
||||
|
||||
|
@ -546,6 +546,15 @@ JS_SetProtoCalled(JSContext*)
|
||||
return sSetProtoCalled;
|
||||
}
|
||||
|
||||
// Defined in jsiter.cpp.
|
||||
extern size_t sCustomIteratorCount;
|
||||
|
||||
JS_FRIEND_API(size_t)
|
||||
JS_GetCustomIteratorCount(JSContext* cx)
|
||||
{
|
||||
return sCustomIteratorCount;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(unsigned)
|
||||
JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp)
|
||||
{
|
||||
|
@ -74,6 +74,9 @@ JS_ObjectCountDynamicSlots(JS::HandleObject obj);
|
||||
extern JS_FRIEND_API(size_t)
|
||||
JS_SetProtoCalled(JSContext* cx);
|
||||
|
||||
extern JS_FRIEND_API(size_t)
|
||||
JS_GetCustomIteratorCount(JSContext* cx);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
JS_NondeterministicGetWeakMapKeys(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
|
||||
|
||||
|
@ -542,6 +542,55 @@ js::GetPropertyKeys(JSContext* cx, HandleObject obj, unsigned flags, AutoIdVecto
|
||||
props);
|
||||
}
|
||||
|
||||
size_t sCustomIteratorCount = 0;
|
||||
|
||||
static inline bool
|
||||
GetCustomIterator(JSContext* cx, HandleObject obj, unsigned flags, MutableHandleObject objp)
|
||||
{
|
||||
if (MOZ_UNLIKELY(!CheckRecursionLimit(cx)))
|
||||
return false;
|
||||
|
||||
RootedValue rval(cx);
|
||||
/* Check whether we have a valid __iterator__ method. */
|
||||
HandlePropertyName name = cx->names().iteratorIntrinsic;
|
||||
if (!GetProperty(cx, obj, obj, name, &rval))
|
||||
return false;
|
||||
|
||||
/* If there is no custom __iterator__ method, we are done here. */
|
||||
if (MOZ_LIKELY(!rval.isObject())) {
|
||||
objp.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cx->runningWithTrustedPrincipals())
|
||||
++sCustomIteratorCount;
|
||||
|
||||
/* Otherwise call it and return that object. */
|
||||
{
|
||||
FixedInvokeArgs<1> args(cx);
|
||||
|
||||
args[0].setBoolean((flags & JSITER_FOREACH) == 0);
|
||||
|
||||
RootedValue thisv(cx, ObjectValue(*obj));
|
||||
if (!js::Call(cx, rval, thisv, args, &rval))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rval.isPrimitive()) {
|
||||
// Ignore the stack when throwing. We can't tell whether we were
|
||||
// supposed to skip over a new.target or not.
|
||||
JSAutoByteString bytes;
|
||||
if (!AtomToPrintableString(cx, name, &bytes))
|
||||
return false;
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
|
||||
JSDVG_IGNORE_STACK, val, nullptr, bytes.ptr());
|
||||
return false;
|
||||
}
|
||||
objp.set(&rval.toObject());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool legacy_iterator_next(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
static inline PropertyIteratorObject*
|
||||
@ -877,6 +926,9 @@ CanStoreInIteratorCache(JSContext* cx, JSObject* obj)
|
||||
return false;
|
||||
if (MOZ_UNLIKELY(clasp->getNewEnumerate() || clasp->getEnumerate()))
|
||||
return false;
|
||||
|
||||
if (MOZ_UNLIKELY(obj->as<NativeObject>().containsPure(cx->names().iteratorIntrinsic)))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(obj->is<UnboxedPlainObject>());
|
||||
}
|
||||
@ -945,12 +997,18 @@ js::GetIterator(JSContext* cx, HandleObject obj, unsigned flags)
|
||||
return Proxy::enumerate(cx, obj);
|
||||
}
|
||||
|
||||
RootedObject res(cx);
|
||||
if (!GetCustomIterator(cx, obj, flags, &res))
|
||||
return nullptr;
|
||||
if (res) {
|
||||
assertSameCompartment(cx, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
AutoIdVector keys(cx);
|
||||
if (!Snapshot(cx, obj, flags, &keys))
|
||||
return nullptr;
|
||||
|
||||
JSObject* res;
|
||||
if (flags & JSITER_FOREACH) {
|
||||
MOZ_ASSERT(numGuards == 0);
|
||||
res = VectorToValueIterator(cx, obj, flags, keys);
|
||||
@ -1022,6 +1080,27 @@ js::ThrowStopIteration(JSContext* cx)
|
||||
|
||||
/*** Iterator objects ****************************************************************************/
|
||||
|
||||
bool
|
||||
js::IteratorConstructor(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() == 0) {
|
||||
ReportMissingArg(cx, args.calleev(), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool keyonly = false;
|
||||
if (args.length() >= 2)
|
||||
keyonly = ToBoolean(args[1]);
|
||||
unsigned flags = JSITER_OWNONLY | (keyonly ? 0 : (JSITER_FOREACH | JSITER_KEYVALUE));
|
||||
|
||||
RootedObject iterobj(cx, ValueToIterator(cx, flags, args[0]));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
args.rval().setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
NativeIteratorNext(JSContext* cx, NativeIterator* ni, MutableHandleValue rval, bool* done)
|
||||
{
|
||||
@ -1054,8 +1133,8 @@ NativeIteratorNext(JSContext* cx, NativeIterator* ni, MutableHandleValue rval, b
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::IsLegacyIterator(HandleValue v)
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsIterator(HandleValue v)
|
||||
{
|
||||
return v.isObject() && v.toObject().hasClass(&PropertyIteratorObject::class_);
|
||||
}
|
||||
@ -1063,7 +1142,7 @@ js::IsLegacyIterator(HandleValue v)
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
legacy_iterator_next_impl(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
MOZ_ASSERT(IsLegacyIterator(args.thisv()));
|
||||
MOZ_ASSERT(IsIterator(args.thisv()));
|
||||
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
@ -1087,9 +1166,15 @@ static bool
|
||||
legacy_iterator_next(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsLegacyIterator, legacy_iterator_next_impl>(cx, args);
|
||||
return CallNonGenericMethod<IsIterator, legacy_iterator_next_impl>(cx, args);
|
||||
}
|
||||
|
||||
static const JSFunctionSpec legacy_iterator_methods[] = {
|
||||
JS_SELF_HOSTED_SYM_FN(iterator, "LegacyIteratorShim", 0, 0),
|
||||
JS_FN("next", legacy_iterator_next, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
size_t
|
||||
PropertyIteratorObject::sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
@ -1126,6 +1211,7 @@ const ClassOps PropertyIteratorObject::classOps_ = {
|
||||
|
||||
const Class PropertyIteratorObject::class_ = {
|
||||
"Iterator",
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_BACKGROUND_FINALIZE,
|
||||
&PropertyIteratorObject::classOps_
|
||||
@ -1605,6 +1691,44 @@ GlobalObject::initStringIteratorProto(JSContext* cx, Handle<GlobalObject*> globa
|
||||
return true;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::InitLegacyIteratorClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
Handle<GlobalObject*> global = obj.as<GlobalObject>();
|
||||
|
||||
if (global->getPrototype(JSProto_Iterator).isObject())
|
||||
return &global->getPrototype(JSProto_Iterator).toObject();
|
||||
|
||||
RootedObject iteratorProto(cx);
|
||||
iteratorProto = GlobalObject::createBlankPrototype(cx, global,
|
||||
&PropertyIteratorObject::class_);
|
||||
if (!iteratorProto)
|
||||
return nullptr;
|
||||
|
||||
NativeIterator* ni = NativeIterator::allocateIterator(cx, 0, 0);
|
||||
if (!ni)
|
||||
return nullptr;
|
||||
|
||||
iteratorProto->as<PropertyIteratorObject>().setNativeIterator(ni);
|
||||
ni->init(nullptr, nullptr, 0 /* flags */, 0, 0);
|
||||
|
||||
Rooted<JSFunction*> ctor(cx);
|
||||
ctor = GlobalObject::createConstructor(cx, IteratorConstructor, cx->names().Iterator, 2);
|
||||
if (!ctor)
|
||||
return nullptr;
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, iteratorProto))
|
||||
return nullptr;
|
||||
if (!DefinePropertiesAndFunctions(cx, iteratorProto, nullptr, legacy_iterator_methods))
|
||||
return nullptr;
|
||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Iterator,
|
||||
ctor, iteratorProto))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &global->getPrototype(JSProto_Iterator).toObject();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::InitStopIterationClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
|
@ -194,6 +194,9 @@ IteratorCloseForException(JSContext* cx, HandleObject obj);
|
||||
void
|
||||
UnwindIteratorForUncatchableException(JSContext* cx, JSObject* obj);
|
||||
|
||||
bool
|
||||
IteratorConstructor(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
extern bool
|
||||
SuppressDeletedProperty(JSContext* cx, HandleObject obj, jsid id);
|
||||
|
||||
@ -217,8 +220,8 @@ ThrowStopIteration(JSContext* cx);
|
||||
extern JSObject*
|
||||
CreateIterResultObject(JSContext* cx, HandleValue value, bool done);
|
||||
|
||||
bool
|
||||
IsLegacyIterator(HandleValue v);
|
||||
extern JSObject*
|
||||
InitLegacyIteratorClass(JSContext* cx, HandleObject obj);
|
||||
|
||||
extern JSObject*
|
||||
InitStopIterationClass(JSContext* cx, HandleObject obj);
|
||||
|
@ -84,7 +84,7 @@
|
||||
real(CompileError, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMCOMPILEERROR)) \
|
||||
real(LinkError, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMLINKERROR)) \
|
||||
real(RuntimeError, InitViaClassSpec, ERROR_CLASP(JSEXN_WASMRUNTIMEERROR)) \
|
||||
imaginary(Iterator, dummy, dummy) \
|
||||
real(Iterator, InitLegacyIteratorClass,OCLASP(PropertyIterator)) \
|
||||
real(StopIteration, InitStopIterationClass, OCLASP(StopIteration)) \
|
||||
real(ArrayBuffer, InitViaClassSpec, OCLASP(ArrayBuffer)) \
|
||||
real(Int8Array, InitViaClassSpec, TYPED_ARRAY_CLASP(Int8)) \
|
||||
|
30
js/src/tests/js1_5/Regress/regress-407957.js
Normal file
30
js/src/tests/js1_5/Regress/regress-407957.js
Normal file
@ -0,0 +1,30 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 407957;
|
||||
var summary = 'Iterator is mutable.';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var obj = {};
|
||||
var saveIterator = Iterator;
|
||||
|
||||
Iterator = obj;
|
||||
reportCompare(obj, Iterator, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
60
js/src/tests/js1_7/GC/regress-381374.js
Normal file
60
js/src/tests/js1_7/GC/regress-381374.js
Normal file
@ -0,0 +1,60 @@
|
||||
// |reftest| skip-if(Android)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 381374;
|
||||
var summary = 'js_AddScopeProperty - overwrite property with watchpoint';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function huh()
|
||||
{
|
||||
var f;
|
||||
|
||||
Iterator; // ???
|
||||
|
||||
if (0 && 0) {
|
||||
eval(""); // ???
|
||||
}
|
||||
|
||||
f = new Function("x = 1");
|
||||
|
||||
try {
|
||||
f();
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
this.watch('x', function(){});
|
||||
this.__defineGetter__('x', new Function());
|
||||
huh();
|
||||
if (typeof gczeal == 'function')
|
||||
{
|
||||
gczeal(2);
|
||||
}
|
||||
|
||||
for (y in [0,1]) { this.__defineSetter__('x', function(){}); }
|
||||
|
||||
if (typeof gczeal == 'function')
|
||||
{
|
||||
gczeal(0);
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
165
js/src/tests/js1_7/extensions/basic-Iterator.js
Normal file
165
js/src/tests/js1_7/extensions/basic-Iterator.js
Normal file
@ -0,0 +1,165 @@
|
||||
/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = "(none)";
|
||||
var summary = "Basic support for accessing iterable objects using Iterator";
|
||||
var actual, expect;
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus(summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var failed = false;
|
||||
|
||||
function Array_equals(a, b)
|
||||
{
|
||||
if (!(a instanceof Array) || !(b instanceof Array))
|
||||
throw new Error("Arguments not both of type Array");
|
||||
if (a.length != b.length)
|
||||
return false;
|
||||
for (var i = 0, sz = a.length; i < sz; i++)
|
||||
if (a[i] !== b[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var iterable = { persistedProp: 17 };
|
||||
|
||||
try
|
||||
{
|
||||
// nothing unusual so far -- verify basic properties
|
||||
for (var i in iterable)
|
||||
{
|
||||
if (i != "persistedProp")
|
||||
throw "no persistedProp!";
|
||||
if (iterable[i] != 17)
|
||||
throw "iterable[\"persistedProp\"] == 17";
|
||||
}
|
||||
|
||||
var keys = ["foo", "bar", "baz"];
|
||||
var vals = [6, 5, 14];
|
||||
|
||||
iterable.__iterator__ =
|
||||
function(keysOnly)
|
||||
{
|
||||
var gen =
|
||||
function()
|
||||
{
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keysOnly)
|
||||
yield keys[i];
|
||||
else
|
||||
yield [keys[i], vals[i]];
|
||||
}
|
||||
};
|
||||
return gen();
|
||||
};
|
||||
|
||||
/* Test [key, value] Iterator */
|
||||
var index = 0;
|
||||
var lastSeen = "INITIALVALUE";
|
||||
var it = Iterator(iterable);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var nextVal = it.next();
|
||||
if (!Array_equals(nextVal, [keys[index], vals[index]]))
|
||||
throw "Iterator(iterable): wrong next result\n" +
|
||||
" expected: " + [keys[index], vals[index]] + "\n" +
|
||||
" actual: " + nextVal;
|
||||
lastSeen = keys[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (lastSeen !== keys[keys.length - 1])
|
||||
throw "Iterator(iterable): not everything was iterated!\n" +
|
||||
" last iterated was: " + lastSeen + "\n" +
|
||||
" error: " + e;
|
||||
if (e !== StopIteration)
|
||||
throw "Iterator(iterable): missing or invalid StopIteration";
|
||||
}
|
||||
|
||||
if (iterable.persistedProp != 17)
|
||||
throw "iterable.persistedProp not persisted!";
|
||||
|
||||
/* Test [key, value] Iterator, called with an explicit |false| parameter */
|
||||
var index = 0;
|
||||
lastSeen = "INITIALVALUE";
|
||||
it = Iterator(iterable, false);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var nextVal = it.next();
|
||||
if (!Array_equals(nextVal, [keys[index], vals[index]]))
|
||||
throw "Iterator(iterable, false): wrong next result\n" +
|
||||
" expected: " + [keys[index], vals[index]] + "\n" +
|
||||
" actual: " + nextVal;
|
||||
lastSeen = keys[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (lastSeen !== keys[keys.length - 1])
|
||||
throw "Iterator(iterable, false): not everything was iterated!\n" +
|
||||
" last iterated was: " + lastSeen + "\n" +
|
||||
" error: " + e;
|
||||
if (e !== StopIteration)
|
||||
throw "Iterator(iterable, false): missing or invalid StopIteration";
|
||||
}
|
||||
|
||||
if (iterable.persistedProp != 17)
|
||||
throw "iterable.persistedProp not persisted!";
|
||||
|
||||
/* Test key-only Iterator */
|
||||
index = 0;
|
||||
lastSeen = undefined;
|
||||
it = Iterator(iterable, true);
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var nextVal = it.next();
|
||||
if (nextVal !== keys[index])
|
||||
throw "Iterator(iterable, true): wrong next result\n" +
|
||||
" expected: " + keys[index] + "\n" +
|
||||
" actual: " + nextVal;
|
||||
lastSeen = keys[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (lastSeen !== keys[keys.length - 1])
|
||||
throw "Iterator(iterable, true): not everything was iterated!\n" +
|
||||
" last iterated was: " + lastSeen + "\n" +
|
||||
" error: " + e;
|
||||
if (e !== StopIteration)
|
||||
throw "Iterator(iterable, true): missing or invalid StopIteration";
|
||||
}
|
||||
|
||||
if (iterable.persistedProp != 17)
|
||||
throw "iterable.persistedProp not persisted!";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
failed = e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
expect = false;
|
||||
actual = failed;
|
||||
|
||||
reportCompare(expect, actual, summary);
|
@ -42,6 +42,38 @@ try
|
||||
throw "iterable[\"persistedProp\"] == 17";
|
||||
}
|
||||
|
||||
var keys = ["foo", "bar", "baz"];
|
||||
var vals = [6, 5, 14];
|
||||
|
||||
iterable.__iterator__ =
|
||||
function(keysOnly)
|
||||
{
|
||||
var gen =
|
||||
function()
|
||||
{
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keysOnly)
|
||||
yield keys[i];
|
||||
else
|
||||
yield [keys[i], vals[i]];
|
||||
}
|
||||
};
|
||||
return gen();
|
||||
};
|
||||
|
||||
// for each sets keysOnly==false
|
||||
var index = 0;
|
||||
for each (var v in iterable)
|
||||
{
|
||||
if (!Array_equals(v, [keys[index], vals[index]]))
|
||||
throw "for-each iteration failed on index=" + index + "!";
|
||||
index++;
|
||||
}
|
||||
if (index != keys.length)
|
||||
throw "not everything iterated! index=" + index +
|
||||
", keys.length=" + keys.length;
|
||||
|
||||
if (iterable.persistedProp != 17)
|
||||
throw "iterable.persistedProp not persisted!";
|
||||
}
|
||||
|
@ -30,6 +30,38 @@ try
|
||||
throw "iterable[\"persistedProp\"] == 17";
|
||||
}
|
||||
|
||||
var keys = ["foo", "bar", "baz"];
|
||||
var vals = [6, 5, 14];
|
||||
|
||||
iterable.__iterator__ =
|
||||
function(keysOnly)
|
||||
{
|
||||
var gen =
|
||||
function()
|
||||
{
|
||||
for (var i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keysOnly)
|
||||
yield keys[i];
|
||||
else
|
||||
yield [keys[i], vals[i]];
|
||||
}
|
||||
};
|
||||
return gen();
|
||||
};
|
||||
|
||||
// for in sets keysOnly==true
|
||||
var index = 0;
|
||||
for (var k in iterable)
|
||||
{
|
||||
if (k != keys[index])
|
||||
throw "for-in iteration failed on keys[\"" + index + "\"]";
|
||||
index++;
|
||||
}
|
||||
if (index != keys.length)
|
||||
throw "not everything iterated! index=" + index +
|
||||
", keys.length=" + keys.length;
|
||||
|
||||
if (iterable.persistedProp != 17)
|
||||
throw "iterable.persistedProp not persisted!";
|
||||
}
|
||||
|
102
js/src/tests/js1_7/extensions/iterator-ctor.js
Normal file
102
js/src/tests/js1_7/extensions/iterator-ctor.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
// See http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Iterators_and_Generators
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = "410725";
|
||||
var summary = "Test of the global Iterator constructor";
|
||||
var actual, expect;
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus(summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
function iteratorToArray(iterator) {
|
||||
var result = [];
|
||||
for (var i in iterator) {
|
||||
result[result.length] = i;
|
||||
}
|
||||
return result.sort();
|
||||
}
|
||||
|
||||
var obj = {a:1, b:2};
|
||||
|
||||
reportCompare('["a", "b"]',
|
||||
uneval(iteratorToArray(obj)),
|
||||
'uneval(iteratorToArray(obj))');
|
||||
|
||||
reportCompare('[["a", 1], ["b", 2]]',
|
||||
uneval(iteratorToArray(Iterator(obj))),
|
||||
'uneval(iteratorToArray(Iterator(obj)))');
|
||||
|
||||
reportCompare('[["a", 1], ["b", 2]]',
|
||||
uneval(iteratorToArray(new Iterator(obj))),
|
||||
'uneval(iteratorToArray(new Iterator(obj)))');
|
||||
|
||||
reportCompare('[["a", 1], ["b", 2]]',
|
||||
uneval(iteratorToArray(Iterator(obj,false))),
|
||||
'uneval(iteratorToArray(Iterator(obj,false)))');
|
||||
|
||||
reportCompare('[["a", 1], ["b", 2]]',
|
||||
uneval(iteratorToArray(new Iterator(obj,false))),
|
||||
'uneval(iteratorToArray(new Iterator(obj,false)))');
|
||||
|
||||
reportCompare('["a", "b"]',
|
||||
uneval(iteratorToArray(Iterator(obj,true))),
|
||||
'uneval(iteratorToArray(Iterator(obj,true)))');
|
||||
|
||||
reportCompare('["a", "b"]',
|
||||
uneval(iteratorToArray(new Iterator(obj,true))),
|
||||
'uneval(iteratorToArray(new Iterator(obj,true)))');
|
||||
|
||||
var flag;
|
||||
var obji = {a:1, b:2};
|
||||
obji.__iterator__ = function (b) { flag = b; yield -1; yield -2; }
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(obji)),
|
||||
'uneval(iteratorToArray(obji))');
|
||||
reportCompare(true, flag, 'uneval(iteratorToArray(obji)) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(Iterator(obji))),
|
||||
'uneval(iteratorToArray(Iterator(obji)))');
|
||||
reportCompare(false, flag, 'uneval(iteratorToArray(Iterator(obji))) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(new Iterator(obji))),
|
||||
'uneval(iteratorToArray(new Iterator(obji)))');
|
||||
reportCompare(false, flag, 'uneval(iteratorToArray(new Iterator(obji))) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(Iterator(obji,false))),
|
||||
'uneval(iteratorToArray(Iterator(obji,false)))');
|
||||
reportCompare(false, flag, 'uneval(iteratorToArray(Iterator(obji,false))) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(new Iterator(obji,false))),
|
||||
'uneval(iteratorToArray(new Iterator(obji,false)))');
|
||||
reportCompare(false, flag, 'uneval(iteratorToArray(new Iterator(obji,false))) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(Iterator(obji,true))),
|
||||
'uneval(iteratorToArray(Iterator(obji,true)))');
|
||||
reportCompare(true, flag, 'uneval(iteratorToArray(Iterator(obji,true))) flag');
|
||||
|
||||
flag = -1;
|
||||
reportCompare('[-1, -2]',
|
||||
uneval(iteratorToArray(new Iterator(obji,true))),
|
||||
'uneval(iteratorToArray(new Iterator(obji,true)))');
|
||||
reportCompare(true, flag, 'uneval(iteratorToArray(new Iterator(obji,true))) flag');
|
45
js/src/tests/js1_7/extensions/regress-346021.js
Normal file
45
js/src/tests/js1_7/extensions/regress-346021.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 346021;
|
||||
var summary = 'Implementing __iterator__ as generator';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var o = { __iterator__: function () { print(12); yield 42; } };
|
||||
|
||||
expect = 42;
|
||||
actual = 0;
|
||||
|
||||
for (let i in Iterator(o))
|
||||
{
|
||||
actual = i;
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
actual = 0;
|
||||
|
||||
for (let i in o)
|
||||
{
|
||||
actual = i; // this doesn't iterate 42
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
46
js/src/tests/js1_7/extensions/regress-354499-01.js
Normal file
46
js/src/tests/js1_7/extensions/regress-354499-01.js
Normal file
@ -0,0 +1,46 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 354499;
|
||||
var summary = 'Iterating over Array elements';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = actual = 'No Crash';
|
||||
|
||||
var obj = {get a(){ return new Object(); }};
|
||||
|
||||
function setter(v)
|
||||
{
|
||||
// Push out obj.a from all temp roots
|
||||
var tmp = { get toString() { return new Object(); }};
|
||||
try { String(tmp); } catch (e) { }
|
||||
gc();
|
||||
}
|
||||
|
||||
Array.prototype.__defineGetter__(0, function() { });
|
||||
Array.prototype.__defineSetter__(0, setter);
|
||||
|
||||
for (var i in Iterator(obj))
|
||||
print(uneval(i));
|
||||
|
||||
delete Array.prototype[0];
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
49
js/src/tests/js1_7/extensions/regress-354499-02.js
Normal file
49
js/src/tests/js1_7/extensions/regress-354499-02.js
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 354499;
|
||||
var summary = 'Iterating over Array elements';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = actual = 'No Crash';
|
||||
|
||||
function get_value()
|
||||
{
|
||||
// Unroot the first element
|
||||
this[0] = 0;
|
||||
|
||||
// Call gc to collect atom corresponding to Math.sqrt(2)
|
||||
gc();
|
||||
}
|
||||
|
||||
var counter = 2;
|
||||
Iterator.prototype.next = function()
|
||||
{
|
||||
if (counter-- <= 0) throw StopIteration;
|
||||
var a = [Math.sqrt(2), 1];
|
||||
a.__defineGetter__(1, get_value);
|
||||
return a;
|
||||
};
|
||||
|
||||
for (i in [1])
|
||||
;
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
34
js/src/tests/js1_7/extensions/regress-354945-01.js
Normal file
34
js/src/tests/js1_7/extensions/regress-354945-01.js
Normal file
@ -0,0 +1,34 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 354945;
|
||||
var summary = 'Do not crash with new Iterator';
|
||||
var expect = 'TypeError: trap __iterator__ for ({__iterator__:(function(){ })}) returned a primitive value';
|
||||
var actual;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
try {
|
||||
var obj = {};
|
||||
obj.__iterator__ = function(){ };
|
||||
for(t in (new Iterator(obj))) { }
|
||||
} catch (ex) {
|
||||
actual = ex.toString();
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
38
js/src/tests/js1_7/extensions/regress-354945-02.js
Normal file
38
js/src/tests/js1_7/extensions/regress-354945-02.js
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 354945;
|
||||
var summary = 'Do not crash with new Iterator';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'TypeError: trap __iterator__ for ({__iterator__:(function(){ })}) returned a primitive value';
|
||||
var obj = {};
|
||||
obj.__iterator__ = function(){ };
|
||||
try
|
||||
{
|
||||
for(t in (obj)) { }
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
6
js/src/tests/js1_7/extensions/regress-589112.js
Normal file
6
js/src/tests/js1_7/extensions/regress-589112.js
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
f = eval("(function(){return x=Iterator(/x/)})")
|
||||
for (a in f()) {}
|
||||
for (d in x) {}
|
||||
|
||||
reportCompare(0, 0, "");
|
23
js/src/tests/js1_7/extensions/regress-590813.js
Normal file
23
js/src/tests/js1_7/extensions/regress-590813.js
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
var actual = '';
|
||||
var expected = 'A0B1B2C0C1C2';
|
||||
|
||||
var x = Iterator([1,2,3], true);
|
||||
|
||||
for (var a in x) {
|
||||
actual += 'A' + a;
|
||||
for (var b in x) {
|
||||
actual += 'B' + b;
|
||||
}
|
||||
}
|
||||
|
||||
var y = Iterator([1,2,3], true);
|
||||
|
||||
for (var c in y) {
|
||||
actual += 'C' + c;
|
||||
}
|
||||
for (var d in y) {
|
||||
actual += 'D' + d;
|
||||
}
|
||||
|
||||
reportCompare(expected, actual, "Handle nested Iterator iteration right");
|
89
js/src/tests/js1_7/geniter/builtin-Iterator-function.js
Normal file
89
js/src/tests/js1_7/geniter/builtin-Iterator-function.js
Normal file
@ -0,0 +1,89 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = "(none)";
|
||||
var summary = "Iterator() test";
|
||||
var actual, expect;
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus(summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
var failed = false;
|
||||
|
||||
function Array_equals(a, b)
|
||||
{
|
||||
if (!(a instanceof Array) || !(b instanceof Array))
|
||||
throw new Error("Arguments not both of type Array");
|
||||
if (a.length != b.length)
|
||||
return false;
|
||||
for (var i = 0, sz = a.length; i < sz; i++)
|
||||
if (a[i] !== b[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
var meow = "meow", oink = "oink", baa = "baa";
|
||||
|
||||
var it = Iterator([meow, oink, baa]);
|
||||
var it2 = Iterator([meow, oink, baa], true);
|
||||
|
||||
try
|
||||
{
|
||||
if (!Array_equals(it.next(), [0, meow]))
|
||||
throw [0, meow];
|
||||
if (!Array_equals(it.next(), [1, oink]))
|
||||
throw [1, oink];
|
||||
if (!Array_equals(it.next(), [2, baa]))
|
||||
throw [2, baa];
|
||||
|
||||
var stopPassed = false;
|
||||
try
|
||||
{
|
||||
it.next();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e === StopIteration)
|
||||
stopPassed = true;
|
||||
}
|
||||
|
||||
if (!stopPassed)
|
||||
throw "it: missing or incorrect StopIteration";
|
||||
|
||||
if (it2.next() != 0)
|
||||
throw "wanted key=0";
|
||||
if (it2.next() != 1)
|
||||
throw "wanted key=1";
|
||||
if (it2.next() != 2)
|
||||
throw "wanted key=2";
|
||||
|
||||
var stopPassed = false;
|
||||
try
|
||||
{
|
||||
it2.next();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e === StopIteration)
|
||||
stopPassed = true;
|
||||
}
|
||||
|
||||
if (!stopPassed)
|
||||
throw "it2: missing or incorrect StopIteration";
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
failed = e;
|
||||
}
|
||||
|
||||
expect = false;
|
||||
actual = failed;
|
||||
|
||||
reportCompare(expect, actual, summary);
|
19
js/src/tests/js1_7/iterable/regress-341496.js
Normal file
19
js/src/tests/js1_7/iterable/regress-341496.js
Normal file
@ -0,0 +1,19 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 341496;
|
||||
var summary = 'Iterators: check that adding properties does not crash';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var iter = Iterator({});
|
||||
for (var i = 0; i != 10*1000; ++i)
|
||||
iter[i] = i;
|
||||
|
||||
reportCompare(expect, actual, summary);
|
42
js/src/tests/js1_7/iterable/regress-354750-01.js
Normal file
42
js/src/tests/js1_7/iterable/regress-354750-01.js
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 354750;
|
||||
var summary = 'Changing Iterator.prototype.next should not affect default iterator';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
Iterator.prototype.next = function() {
|
||||
throw "This should not be thrown";
|
||||
}
|
||||
|
||||
expect = 'No exception';
|
||||
actual = 'No exception';
|
||||
try
|
||||
{
|
||||
for (var i in [])
|
||||
{
|
||||
}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex;
|
||||
}
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
28
js/src/tests/js1_7/iterable/regress-355025.js
Normal file
28
js/src/tests/js1_7/iterable/regress-355025.js
Normal file
@ -0,0 +1,28 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 355025;
|
||||
var summary = 'Test regression from bug 354750 - Iterable()';
|
||||
var actual = 'No Error';
|
||||
var expect = 'No Error';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
Iterator([]);
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
37
js/src/tests/js1_7/iterable/regress-355090.js
Normal file
37
js/src/tests/js1_7/iterable/regress-355090.js
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 355090;
|
||||
var summary = 'Iterator(8) is a function';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
expect = 'No Error';
|
||||
actual = 'No Error';
|
||||
try
|
||||
{
|
||||
Iterator(8);
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
actual = ex + '';
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
24
js/src/tests/js1_7/iterable/regress-568056.js
Normal file
24
js/src/tests/js1_7/iterable/regress-568056.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var BUGNUMBER = 568056;
|
||||
var summary = "Iterator(obj) must not go up obj's prototype chain";
|
||||
|
||||
var foo = {
|
||||
z: 9,
|
||||
};
|
||||
|
||||
var bar = {
|
||||
__proto__: foo,
|
||||
a: 1,
|
||||
b: 2,
|
||||
};
|
||||
|
||||
var results = [];
|
||||
for each (let [key, value] in Iterator(bar))
|
||||
results.push(key + ":" + value);
|
||||
|
||||
var actual = results.join(';')
|
||||
var expect = "a:1;b:2";
|
||||
|
||||
reportCompare(expect, actual, summary);
|
44
js/src/tests/js1_7/regress/regress-385393-05.js
Normal file
44
js/src/tests/js1_7/regress/regress-385393-05.js
Normal file
@ -0,0 +1,44 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 385393;
|
||||
var summary = 'Regression test for bug 385393';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function c(gen)
|
||||
{
|
||||
Iterator;
|
||||
|
||||
"" + gen;
|
||||
|
||||
for (var i in gen())
|
||||
;
|
||||
}
|
||||
|
||||
function gen()
|
||||
{
|
||||
({}).hasOwnProperty();
|
||||
yield;
|
||||
}
|
||||
|
||||
c(gen);
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
30
js/src/tests/js1_7/regress/regress-407957.js
Normal file
30
js/src/tests/js1_7/regress/regress-407957.js
Normal file
@ -0,0 +1,30 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 407957;
|
||||
var summary = 'Iterator is mutable.';
|
||||
var actual = '';
|
||||
var expect = '';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
var obj = {};
|
||||
var saveIterator = Iterator;
|
||||
|
||||
Iterator = obj;
|
||||
reportCompare(obj, Iterator, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -206,6 +206,7 @@
|
||||
macro(isPrototypeOf, isPrototypeOf, "isPrototypeOf") \
|
||||
macro(IterableToList, IterableToList, "IterableToList") \
|
||||
macro(iterate, iterate, "iterate") \
|
||||
macro(iteratorIntrinsic, iteratorIntrinsic, "__iterator__") \
|
||||
macro(join, join, "join") \
|
||||
macro(js, js, "js") \
|
||||
macro(keys, keys, "keys") \
|
||||
|
@ -439,6 +439,10 @@ class GlobalObject : public NativeObject
|
||||
|
||||
TypedObjectModuleObject& getTypedObjectModule() const;
|
||||
|
||||
JSObject* getLegacyIteratorPrototype() {
|
||||
return &getPrototype(JSProto_Iterator).toObject();
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
getOrCreateCollatorPrototype(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
return getOrCreateObject(cx, global, COLLATOR_PROTO, initIntlObject);
|
||||
|
@ -687,6 +687,9 @@ EnsureParserCreatedClasses(JSContext* cx, ParseTaskKind kind)
|
||||
if (!EnsureConstructor(cx, global, JSProto_RegExp))
|
||||
return false; // needed by regular expression literals
|
||||
|
||||
if (!EnsureConstructor(cx, global, JSProto_Iterator))
|
||||
return false; // needed by ???
|
||||
|
||||
if (!GlobalObject::initStarGenerators(cx, global))
|
||||
return false; // needed by function*() {} and generator comprehensions
|
||||
|
||||
@ -1794,7 +1797,8 @@ GlobalHelperThreadState::mergeParseTaskCompartment(JSContext* cx, ParseTask* par
|
||||
JSProtoKey key = JS::IdentifyStandardPrototype(protoObj);
|
||||
if (key != JSProto_Null) {
|
||||
MOZ_ASSERT(key == JSProto_Object || key == JSProto_Array ||
|
||||
key == JSProto_Function || key == JSProto_RegExp);
|
||||
key == JSProto_Function || key == JSProto_RegExp ||
|
||||
key == JSProto_Iterator);
|
||||
newProto = GetBuiltinPrototypePure(global, key);
|
||||
} else if (protoObj == parseTaskStarGenFunctionProto) {
|
||||
newProto = global->getStarGeneratorFunctionPrototype();
|
||||
|
@ -2235,6 +2235,10 @@ GetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
|
||||
if (script->selfHosted())
|
||||
return true;
|
||||
|
||||
// We may just be checking if that object has an iterator.
|
||||
if (JSID_IS_ATOM(id, cx->names().iteratorIntrinsic))
|
||||
return true;
|
||||
|
||||
// Do not warn about tests like (obj[prop] == undefined).
|
||||
pc += CodeSpec[*pc].length;
|
||||
if (Detecting(cx, script, pc))
|
||||
|
@ -3236,6 +3236,11 @@ nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext* cx, MutableHandleVal
|
||||
if (!JS_DefineProperty(cx, obj, "setProto", v, attrs))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
i = JS_GetCustomIteratorCount(cx);
|
||||
v.setDouble(i);
|
||||
if (!JS_DefineProperty(cx, obj, "customIter", v, attrs))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rval.setObject(*obj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=500931
|
||||
var ifr = document.getElementById('ifr');
|
||||
var docnodes = ifr.contentDocument.body.childNodes;
|
||||
var index, value;
|
||||
for (let i of Object.entries(docnodes)) {
|
||||
for (let i in Iterator(docnodes)) {
|
||||
index = i[0], value = i[1];
|
||||
}
|
||||
is(index, "0", "enumerated the 0th element");
|
||||
is(index, 0, "enumerated the 0th element");
|
||||
ok(value instanceof Text, "the 0th element was a text node");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -189,6 +189,7 @@ Structure:
|
||||
|
||||
"js" : {
|
||||
"setProto": <unsigned integer>, // Number of times __proto__ is set
|
||||
"customIter": <unsigned integer> // Number of times __iterator__ is used (i.e., is found for a for-in loop)
|
||||
}
|
||||
|
||||
maximalNumberOfConcurrentThreads
|
||||
|
Loading…
Reference in New Issue
Block a user