summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/extensions/newer-type-functions-caller-arguments.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/extensions/newer-type-functions-caller-arguments.js94
1 files changed, 94 insertions, 0 deletions
diff --git a/js/src/tests/non262/extensions/newer-type-functions-caller-arguments.js b/js/src/tests/non262/extensions/newer-type-functions-caller-arguments.js
new file mode 100644
index 0000000000..8f2d47a11d
--- /dev/null
+++ b/js/src/tests/non262/extensions/newer-type-functions-caller-arguments.js
@@ -0,0 +1,94 @@
+// Tests that newer-type functions (i.e. anything not defined by regular function declarations and
+// expressions) throw when accessing their 'arguments' and 'caller' properties.
+
+// 9.2.7 (AddRestrictedFunctionProperties) defines accessors on Function.prototype which throw on
+// every 'get' and 'set' of 'caller' and 'arguments'.
+// Additionally, 16.2 (Forbidden Extensions) forbids adding properties to all non-"legacy" function
+// declarations and expressions. This creates the effect that all newer-style functions act like
+// strict-mode functions when accessing their 'caller' and 'arguments' properties.
+
+const container = {
+ async asyncMethod() {},
+ *genMethod() {},
+ method() {},
+ get getterMethod() {},
+ set setterMethod(x) {},
+};
+
+function* genDecl(){}
+async function asyncDecl(){}
+class classDecl {}
+class extClassDecl extends Object {}
+class classDeclExplicitCtor { constructor(){} }
+class extClassDeclExplicitCtor extends Object { constructor(){} }
+
+const functions = [
+ // Declarations
+ genDecl,
+ asyncDecl,
+ classDecl,
+ extClassDecl,
+ classDeclExplicitCtor,
+ extClassDeclExplicitCtor,
+
+ // Expressions
+ async function(){},
+ function*(){},
+ () => {},
+ async () => {},
+ class {},
+ class extends Object {},
+ class { constructor(){} },
+ class extends Object { constructor(){} },
+
+ // Methods
+ container.asyncMethod,
+ container.genMethod,
+ container.method,
+ Object.getOwnPropertyDescriptor(container, "getterMethod").get,
+ Object.getOwnPropertyDescriptor(container, "setterMethod").set,
+
+ // Bound functions
+ function(){}.bind(),
+
+ // Built-ins (native and self-hosted)
+ Function,
+ Function.prototype.bind,
+];
+
+const supportsAsyncGenerator = (function() {
+ try {
+ eval("async function* f(){}");
+ return true;
+ } catch (e) {
+ return false;
+ }
+})();
+
+if (supportsAsyncGenerator) {
+eval(`
+ async function* asyncGenDecl(){}
+
+ functions.push(asyncGenDecl);
+ functions.push(async function*(){});
+ functions.push({async* asyncGenerator(){}}.asyncGenerator);
+`);
+}
+
+functions.forEach(f => {
+ checkArgumentsAccess(f);
+ checkCallerAccess(f);
+});
+
+function checkArgumentsAccess(f) {
+ assertThrowsInstanceOf(() => f.arguments, TypeError,
+ `Expected 'arguments' property access to throw on ${f}`);
+}
+
+function checkCallerAccess(f) {
+ assertThrowsInstanceOf(() => f.caller, TypeError,
+ `Expected 'caller' property access to throw on ${f}`);
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);