ES6: Classes: Should be allowed to create a static method with name "arguments"
authorgskachkov@gmail.com <gskachkov@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Sep 2016 08:17:39 +0000 (08:17 +0000)
committergskachkov@gmail.com <gskachkov@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Sep 2016 08:17:39 +0000 (08:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=152985

Reviewed by Keith Miller.

Source/JavaScriptCore:

Current patch covered 16.2 Forbidden Extensions - first topic
(https://tc39.github.io/ecma262/#sec-forbidden-extensions) ECMAScript Functions
should not have own properties named "caller" or "arguments".
Also added possibility to declare static methods and getters with
name 'arguments' and 'caller' for classes. i.e.:
class A { static arguments() { return 'value'; } }
A.arguments() === 'value';
To implement this patch 'caller' and 'arguments' were put to the FunctionPrototype
object. Also was changed approach to init throwTypeErrorArgumentsCalleeAndCallerGetterSetter
property from Lazy to common because it necessary to use execState during init of the accessors
properties.

* runtime/Executable.h:
* runtime/FunctionPrototype.cpp:
(JSC::FunctionPrototype::initRestrictedProperties):
(JSC::FunctionPrototype::addFunctionProperties): Deleted.
* runtime/FunctionPrototype.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::getOwnNonIndexPropertyNames):
(JSC::JSFunction::put):
(JSC::JSFunction::deleteProperty):
(JSC::JSFunction::defineOwnProperty):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::throwTypeErrorArgumentsCalleeAndCallerGetterSetter):

JSTests:

* test262.yaml:

LayoutTests:

* js/Object-getOwnPropertyNames-expected.txt:
* js/basic-strict-mode-expected.txt:
* js/class-method-and-constructor-properties-expected.txt: Removed.
* js/class-syntax-method-names-expected.txt:
* js/es6-function-properties-expected.txt: Added.
* js/es6-function-properties.html: Copied from LayoutTests/js/class-method-and-constructor-properties.html.
* js/kde/script-tests/function_arguments.js:
(f):
* js/non-strict-function-properties-expected.txt: Added.
* js/non-strict-function-properties.html: Renamed from LayoutTests/js/class-method-and-constructor-properties.html.
* js/script-tests/Object-getOwnPropertyNames.js:
* js/script-tests/basic-strict-mode.js:
* js/script-tests/class-method-and-constructor-properties.js: Removed.
(shouldThrow): Deleted.
(shouldBe): Deleted.
(A): Deleted.
(B): Deleted.
(C): Deleted.
(D): Deleted.
(E.prototype.getItem): Deleted.
(E): Deleted.
(F.prototype.getElement): Deleted.
(F): Deleted.
(G.prototype.get item): Deleted.
(G): Deleted.
(H.prototype.caller): Deleted.
(H.prototype.arguments): Deleted.
(H): Deleted.
* js/script-tests/class-syntax-method-names.js:
* js/script-tests/es6-function-properties.js: Added.
(shouldThrow):
(shouldBe):
(A):
(B):
(C):
(D):
(E.prototype.getItem):
(E):
(F.prototype.getElement):
(F):
(G.prototype.get item):
(G):
(check):
(arr):
(H.prototype.caller):
(H.prototype.arguments):
(H):
(J.prototype.gen):
(J.gen):
(J):
* js/script-tests/non-strict-function-properties.js: Added.
(foo):
(boo):
(f):
(g):
(doSetCaller):
(doSetArguments):
* js/script-tests/strict-throw-type-error.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205856 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
JSTests/ChangeLog
JSTests/test262.yaml
LayoutTests/ChangeLog
LayoutTests/js/Object-getOwnPropertyNames-expected.txt
LayoutTests/js/basic-strict-mode-expected.txt
LayoutTests/js/class-method-and-constructor-properties-expected.txt [deleted file]
LayoutTests/js/class-syntax-method-names-expected.txt
LayoutTests/js/es6-function-properties-expected.txt [new file with mode: 0644]
LayoutTests/js/es6-function-properties.html [moved from LayoutTests/js/class-method-and-constructor-properties.html with 61% similarity]
LayoutTests/js/kde/script-tests/function_arguments.js
LayoutTests/js/non-strict-function-properties-expected.txt [new file with mode: 0644]
LayoutTests/js/non-strict-function-properties.html [new file with mode: 0644]
LayoutTests/js/script-tests/Object-getOwnPropertyNames.js
LayoutTests/js/script-tests/basic-strict-mode.js
LayoutTests/js/script-tests/class-method-and-constructor-properties.js [deleted file]
LayoutTests/js/script-tests/class-syntax-method-names.js
LayoutTests/js/script-tests/es6-function-properties.js [new file with mode: 0644]
LayoutTests/js/script-tests/non-strict-function-properties.js [new file with mode: 0644]
LayoutTests/js/script-tests/strict-throw-type-error.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/FunctionPrototype.cpp
Source/JavaScriptCore/runtime/FunctionPrototype.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h

index 9b5c7fa..703c76f 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-12  Skachkov Oleksandr  <gskachkov@gmail.com>
+
+        ES6: Classes: Should be allowed to create a static method with name "arguments"
+        https://bugs.webkit.org/show_bug.cgi?id=152985
+
+        Reviewed by Keith Miller.
+
+        * test262.yaml:
+
 2016-09-12  Saam Barati  <sbarati@apple.com>
 
         Speed up Function.prototype.bind a bit by making it a builtin
index a9a6f55..ab87bb0 100644 (file)
 - path: test262/test/built-ins/Function/S15.3_A3_T6.js
   cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
 - path: test262/test/built-ins/Function/StrictFunction_restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
 - path: test262/test/built-ins/Function/instance-name.js
   cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js", "../../../harness/propertyHelper.js"], []
 - path: test262/test/built-ins/Function/instance-name.js
 - path: test262/test/built-ins/Function/prototype/name.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], [:strict]
 - path: test262/test/built-ins/Function/prototype/restricted-property-arguments.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], []
 - path: test262/test/built-ins/Function/prototype/restricted-property-arguments.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], [:strict]
 - path: test262/test/built-ins/Function/prototype/restricted-property-caller.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], []
 - path: test262/test/built-ins/Function/prototype/restricted-property-caller.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/propertyHelper.js"], [:strict]
 - path: test262/test/built-ins/Function/prototype/toString/AsyncFunction.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/built-ins/Function/prototype/toString/AsyncFunction.js
 - path: test262/test/built-ins/GeneratorFunction/instance-prototype.js
   cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js", "../../../harness/propertyHelper.js"], [:strict]
 - path: test262/test/built-ins/GeneratorFunction/instance-restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
 - path: test262/test/built-ins/GeneratorFunction/instance-restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
 - path: test262/test/built-ins/GeneratorFunction/instance-yield-expr-in-param.js
   cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
 - path: test262/test/built-ins/GeneratorFunction/instance-yield-expr-in-param.js
 - path: test262/test/built-ins/ThrowTypeError/throws-type-error.js
   cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
 - path: test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
 - path: test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
-  cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:strict]
 - path: test262/test/built-ins/ThrowTypeError/unique-per-realm-non-simple.js
   cmd: runTest262 :fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], []
 - path: test262/test/built-ins/ThrowTypeError/unique-per-realm-non-simple.js
 - path: test262/test/language/expressions/array/spread-sngl-literal.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/arrow-function/ArrowFunction_restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/arrow-function/ArrowFunction_restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/arrow-function/arrow/binding-tests-1.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/arrow-function/arrow/binding-tests-2.js
 - path: test262/test/language/expressions/class/params-dflt-meth-static-rest.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/class/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/class/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/expressions/class/scope-gen-meth-paramsbody-var-close.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/expressions/class/scope-gen-meth-paramsbody-var-close.js
 - path: test262/test/language/statements/class/definition/methods-gen-yield-weak-binding.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/methods-named-eval-arguments.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/methods-named-eval-arguments.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/methods-restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/methods-restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/methods.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/methods.js
 - path: test262/test/language/statements/class/definition/setters-prop-desc.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
 - path: test262/test/language/statements/class/definition/setters-restricted-ids.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/setters-restricted-ids.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/definition/side-effects-in-extends.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/definition/side-effects-in-extends.js
 - path: test262/test/language/statements/class/params-dflt-meth-static-rest.js
   cmd: runTest262 :normal, "SyntaxError", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/class/scope-gen-meth-paramsbody-var-close.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/class/scope-gen-meth-paramsbody-var-close.js
 - path: test262/test/language/statements/generators/prototype-value.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/generators/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/generators/restricted-properties.js
-  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
+  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:strict]
 - path: test262/test/language/statements/generators/return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
 - path: test262/test/language/statements/generators/return.js
index 851480b..2347251 100644 (file)
@@ -1,3 +1,69 @@
+2016-09-13  Skachkov Oleksandr  <gskachkov@gmail.com>
+
+        ES6: Classes: Should be allowed to create a static method with name "arguments"
+        https://bugs.webkit.org/show_bug.cgi?id=152985
+
+        Reviewed by Keith Miller.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/basic-strict-mode-expected.txt:
+        * js/class-method-and-constructor-properties-expected.txt: Removed.
+        * js/class-syntax-method-names-expected.txt:
+        * js/es6-function-properties-expected.txt: Added.
+        * js/es6-function-properties.html: Copied from LayoutTests/js/class-method-and-constructor-properties.html.
+        * js/kde/script-tests/function_arguments.js:
+        (f):
+        * js/non-strict-function-properties-expected.txt: Added.
+        * js/non-strict-function-properties.html: Renamed from LayoutTests/js/class-method-and-constructor-properties.html.
+        * js/script-tests/Object-getOwnPropertyNames.js:
+        * js/script-tests/basic-strict-mode.js:
+        * js/script-tests/class-method-and-constructor-properties.js: Removed.
+        (shouldThrow): Deleted.
+        (shouldBe): Deleted.
+        (A): Deleted.
+        (B): Deleted.
+        (C): Deleted.
+        (D): Deleted.
+        (E.prototype.getItem): Deleted.
+        (E): Deleted.
+        (F.prototype.getElement): Deleted.
+        (F): Deleted.
+        (G.prototype.get item): Deleted.
+        (G): Deleted.
+        (H.prototype.caller): Deleted.
+        (H.prototype.arguments): Deleted.
+        (H): Deleted.
+        * js/script-tests/class-syntax-method-names.js:
+        * js/script-tests/es6-function-properties.js: Added.
+        (shouldThrow):
+        (shouldBe):
+        (A):
+        (B):
+        (C):
+        (D):
+        (E.prototype.getItem):
+        (E):
+        (F.prototype.getElement):
+        (F):
+        (G.prototype.get item):
+        (G):
+        (check):
+        (arr):
+        (H.prototype.caller):
+        (H.prototype.arguments):
+        (H):
+        (J.prototype.gen):
+        (J.gen):
+        (J):
+        * js/script-tests/non-strict-function-properties.js: Added.
+        (foo):
+        (boo):
+        (f):
+        (g):
+        (doSetCaller):
+        (doSetArguments):
+        * js/script-tests/strict-throw-type-error.js:
+
 2016-09-12  Youenn Fablet  <youenn@apple.com>
 
         ScriptElement should use FetchOptions::mode according its crossOrigin attribute
index ffbd915..c22575f 100644 (file)
@@ -44,7 +44,7 @@ PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name']
 PASS getSortedOwnPropertyNames(Object) is ['assign', 'create', 'defineProperties', 'defineProperty', 'entries', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyDescriptors', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'values']
 PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
 PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
-PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']
+PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']
 PASS getSortedOwnPropertyNames(Array) is ['from', 'isArray', 'length', 'name', 'of', 'prototype']
 PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']
 PASS getSortedOwnPropertyNames(String) is ['fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']
index 528e421..a305ecc 100644 (file)
@@ -72,9 +72,11 @@ PASS (function a(a){'use strict'; return a+2; })(40) is 42
 PASS var foo = function a(a){'use strict'; return a+2; }; foo(40) is 42
 PASS var o = {foo: function a(a){'use strict'; return a+2; } }; o.foo(40) is 42
 PASS "caller" in function(){"use strict"} is true
-PASS (function(){"use strict";}).hasOwnProperty("caller") is true
+PASS (function(){"use strict";}).hasOwnProperty("caller") is false
+PASS (function(){"use strict";}).__proto__.hasOwnProperty("caller") is true
 PASS "arguments" in function(){"use strict"} is true
-PASS (function(){"use strict";}).hasOwnProperty("arguments") is true
+PASS (function(){"use strict";}).hasOwnProperty("arguments") is false
+PASS (function(){"use strict";}).__proto__.hasOwnProperty("arguments") is true
 PASS 'use strict'; (function (){with(1){};}) threw exception SyntaxError: 'with' statements are not valid in strict mode..
 PASS (function(){'use strict'; (function (){with(1){};})}) threw exception SyntaxError: 'with' statements are not valid in strict mode..
 PASS 'use strict'; (function (){var a; delete a;}) threw exception SyntaxError: Cannot delete unqualified property 'a' in strict mode..
@@ -179,14 +181,14 @@ PASS (function (a){'use strict'; var local; (function (){local;})(); arguments[0
 PASS (function (){'use strict';  var local; (function (){local;})(); arguments[0]=true; return arguments; })()[0] is true
 PASS 'use strict'; (function (){var a = true; eval('var a = false'); return a; })() is true
 PASS (function (){var a = true; eval('"use strict"; var a = false'); return a; })() is true
-PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'arguments').value; })() is undefined.
-PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'caller').value; })() is undefined.
+PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'arguments').value; })() is undefined.
+PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'caller').value; })() is undefined.
 PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').value; })() is undefined.
 PASS (function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller').value; })() is undefined.
 PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'caller'); return descriptor.get === descriptor.set; })() is true
 PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'callee'); return descriptor.get === descriptor.set; })() is true
-PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'caller'); return descriptor.get === descriptor.set; })() is true
-PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })() is true
+PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })() is true
+PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'arguments'); return descriptor.get === descriptor.set; })() is true
 PASS 'use strict'; (function f() { for(var i in this); })(); true; is true
 PASS 'use strict'̻ threw exception SyntaxError: Invalid character '\u0827'.
 PASS (function(){'use strict'̻}) threw exception SyntaxError: Invalid character '\u0827'.
@@ -212,7 +214,7 @@ PASS (function () {'use strict';  try { throw 1; } catch (e) { aGlobal = true; }
 PASS try { throw 1; } catch (e) { aGlobal = true; } is true
 PASS (function () { try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true
 PASS (function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal; is true
-PASS String(Object.getOwnPropertyDescriptor(function() { "use strict"; }, "caller").get) is 'function () {\n    [native code]\n}'
+PASS String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get) is 'function () {\n    [native code]\n}'
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/js/class-method-and-constructor-properties-expected.txt b/LayoutTests/js/class-method-and-constructor-properties-expected.txt
deleted file mode 100644 (file)
index b9934c7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Tests for ES6 class method and constructor properties
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS (new A()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new A()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new B()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new B()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new C()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new C()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new D()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new D()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new E()).getItem.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new E()).getItem.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new F()).getItem.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new F()).getItem.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new F()).getElement.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new F()).getElement.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new G()).item.caller:::undefined
-PASS (new G()).item.arguments:::undefined
-PASS H.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS H.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new H()).caller():::"value"
-PASS (new H()).arguments():::"value"
-PASS (new H()).caller.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS (new H()).caller.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
-PASS successfullyParsed:::true
-
-TEST COMPLETE
-
index d86aa41..aecfb07 100644 (file)
@@ -20,6 +20,32 @@ PASS class A { static get get() { return 104; } }; A.get is 104
 PASS class A { static get set() { return 105; } }; A.set is 105
 PASS setterValue = undefined; class A { static set get(x) { setterValue = x; } }; A.get = 106; setterValue is 106
 PASS setterValue = undefined; class A { static set set(x) { setterValue = x; } }; A.set = 107; setterValue is 107
+PASS class X {static arguments() {}} did not throw exception.
+PASS class X {static caller() {}} did not throw exception.
+PASS (class X {static arguments() {return staticMethodValue;}}).arguments() is staticMethodValue
+PASS (class X {static caller() {return staticMethodValue;}}).caller() is staticMethodValue
+PASS (class X {static arguments() {return staticMethodValue;}}).hasOwnProperty('arguments') is true
+PASS (class X {static caller() {return staticMethodValue;}}).hasOwnProperty('caller') is true
+PASS class X {static get arguments() {}} did not throw exception.
+PASS class X {static get caller() {}} did not throw exception.
+PASS (class X {static get arguments() {return staticMethodValue;}}).arguments is staticMethodValue
+PASS (class X {static get caller() {return staticMethodValue;}}).caller is staticMethodValue
+PASS (class X {static get arguments() {return staticMethodValue;}}).hasOwnProperty('arguments') is true
+PASS (class X {static get caller() {return staticMethodValue;}}).hasOwnProperty('caller') is true
+PASS class X {static caller() {return staticMethodValue;}};X.arguments = function(){} threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode..
+PASS class X {static arguments() {return staticMethodValue;}}; X.caller = function(){} threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode..
+PASS class X {static caller() {return "";}} X.caller = function(){ return staticMethodValue; };X.caller() is staticMethodValue
+PASS class X {static arguments() {return "";}}; X.arguments = function(){ return staticMethodValue; };X.arguments() is staticMethodValue
+PASS class X {static caller() {return "";}} X["caller"] = function(){ return staticMethodValue; };X.caller() is staticMethodValue
+PASS class X {static arguments() {return "";}}; X["arguments"] = function(){ return staticMethodValue; };X.arguments() is staticMethodValue
+PASS class X {static *caller() {yield staticMethodValue;}}; X.caller().next().value is staticMethodValue
+PASS class X {static *arguments() {yield staticMethodValue;}}; X.arguments().next().value is staticMethodValue
+PASS class X {static *caller() {yield;}}; X["caller"] = function*(){yield staticMethodValue;}; X.caller().next().value is staticMethodValue
+PASS class X {static *arguments() {yield;}}; X["arguments"] = function*(){yield staticMethodValue;}; X.arguments().next().value is staticMethodValue
+PASS class X {*caller() {yield staticMethodValue;}}; let x = new X; x.caller().next().value is staticMethodValue
+PASS class X {*arguments() {yield staticMethodValue;}}; let x = new X; x.arguments().next().value is staticMethodValue
+PASS class X {*caller() {yield;}}; let x = new X; x["caller"] = function*(){yield staticMethodValue;}; x.caller().next().value is staticMethodValue
+PASS class X {*arguments() {yield;}}; let x = new X; x["arguments"] = function*(){yield staticMethodValue;}; x.arguments().next().value is staticMethodValue
 
 Instance methods with computed names
 PASS class A { ['a' + 'b']() { return 211; } }; (new A).ab() is 211
diff --git a/LayoutTests/js/es6-function-properties-expected.txt b/LayoutTests/js/es6-function-properties-expected.txt
new file mode 100644 (file)
index 0000000..7c27413
--- /dev/null
@@ -0,0 +1,481 @@
+Tests for ES6 class method and constructor properties
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+a.constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+(new A()).constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS a.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.hasOwnProperty("caller"):::false
+PASS a.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(a.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(a.constructor, "arguments"):::undefined
+PASS delete a.constructor.caller:::true
+PASS delete a.constructor["caller"]:::true
+PASS delete a.constructor.arguments:::true
+PASS delete a.constructor["arguments"]:::true
+PASS a.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS a.constructor.hasOwnProperty("caller"):::false
+PASS a.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(a.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(a.constructor, "arguments"):::undefined
+PASS delete a.constructor.caller:::true
+PASS delete a.constructor["caller"]:::true
+PASS delete a.constructor.arguments:::true
+PASS delete a.constructor["arguments"]:::true
+PASS (new A()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new A()).constructor.hasOwnProperty("caller"):::false
+PASS (new A()).constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new A()).constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new A()).constructor, "arguments"):::undefined
+PASS delete (new A()).constructor.caller:::true
+PASS delete (new A()).constructor["caller"]:::true
+PASS delete (new A()).constructor.arguments:::true
+PASS delete (new A()).constructor["arguments"]:::true
+b.constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+(new B()).constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS b.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS b.constructor.hasOwnProperty("caller"):::false
+PASS b.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(b.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(b.constructor, "arguments"):::undefined
+PASS delete b.constructor.caller:::true
+PASS delete b.constructor["caller"]:::true
+PASS delete b.constructor.arguments:::true
+PASS delete b.constructor["arguments"]:::true
+PASS (new B()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new B()).constructor.hasOwnProperty("caller"):::false
+PASS (new B()).constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new B()).constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new B()).constructor, "arguments"):::undefined
+PASS delete (new B()).constructor.caller:::true
+PASS delete (new B()).constructor["caller"]:::true
+PASS delete (new B()).constructor.arguments:::true
+PASS delete (new B()).constructor["arguments"]:::true
+c.constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+(new C()).constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS c.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS c.constructor.hasOwnProperty("caller"):::false
+PASS c.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(c.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(c.constructor, "arguments"):::undefined
+PASS delete c.constructor.caller:::true
+PASS delete c.constructor["caller"]:::true
+PASS delete c.constructor.arguments:::true
+PASS delete c.constructor["arguments"]:::true
+PASS (new C()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new C()).constructor.hasOwnProperty("caller"):::false
+PASS (new C()).constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new C()).constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new C()).constructor, "arguments"):::undefined
+PASS delete (new C()).constructor.caller:::true
+PASS delete (new C()).constructor["caller"]:::true
+PASS delete (new C()).constructor.arguments:::true
+PASS delete (new C()).constructor["arguments"]:::true
+c.constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+(new D()).constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS d.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS d.constructor.hasOwnProperty("caller"):::false
+PASS d.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(d.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(d.constructor, "arguments"):::undefined
+PASS delete d.constructor.caller:::true
+PASS delete d.constructor["caller"]:::true
+PASS delete d.constructor.arguments:::true
+PASS delete d.constructor["arguments"]:::true
+PASS (new D()).constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new D()).constructor.hasOwnProperty("caller"):::false
+PASS (new D()).constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new D()).constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new D()).constructor, "arguments"):::undefined
+PASS delete (new D()).constructor.caller:::true
+PASS delete (new D()).constructor["caller"]:::true
+PASS delete (new D()).constructor.arguments:::true
+PASS delete (new D()).constructor["arguments"]:::true
+e.constructor
+PASS 'length,name,prototype':::'length,name,prototype'
+(new E()).getItem
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS e.constructor.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS e.constructor.hasOwnProperty("caller"):::false
+PASS e.constructor.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(e.constructor, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(e.constructor, "arguments"):::undefined
+PASS delete e.constructor.caller:::true
+PASS delete e.constructor["caller"]:::true
+PASS delete e.constructor.arguments:::true
+PASS delete e.constructor["arguments"]:::true
+PASS (new E()).getItem.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new E()).getItem.hasOwnProperty("caller"):::false
+PASS (new E()).getItem.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new E()).getItem, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new E()).getItem, "arguments"):::undefined
+PASS delete (new E()).getItem.caller:::true
+PASS delete (new E()).getItem["caller"]:::true
+PASS delete (new E()).getItem.arguments:::true
+PASS delete (new E()).getItem["arguments"]:::true
+f.getItem
+PASS 'length,name,prototype':::'length,name,prototype'
+f.getElement
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS f.getItem.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getItem.hasOwnProperty("caller"):::false
+PASS f.getItem.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(f.getItem, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(f.getItem, "arguments"):::undefined
+PASS delete f.getItem.caller:::true
+PASS delete f.getItem["caller"]:::true
+PASS delete f.getItem.arguments:::true
+PASS delete f.getItem["arguments"]:::true
+PASS f.getElement.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS f.getElement.hasOwnProperty("caller"):::false
+PASS f.getElement.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(f.getElement, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(f.getElement, "arguments"):::undefined
+PASS delete f.getElement.caller:::true
+PASS delete f.getElement["caller"]:::true
+PASS delete f.getElement.arguments:::true
+PASS delete f.getElement["arguments"]:::true
+(new F()).getItem
+PASS 'length,name,prototype':::'length,name,prototype'
+(new F()).getElement
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS (new F()).getItem.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getItem.hasOwnProperty("caller"):::false
+PASS (new F()).getItem.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new F()).getItem, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new F()).getItem, "arguments"):::undefined
+PASS delete (new F()).getItem.caller:::true
+PASS delete (new F()).getItem["caller"]:::true
+PASS delete (new F()).getItem.arguments:::true
+PASS delete (new F()).getItem["arguments"]:::true
+PASS (new F()).getElement.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new F()).getElement.hasOwnProperty("caller"):::false
+PASS (new F()).getElement.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new F()).getElement, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new F()).getElement, "arguments"):::undefined
+PASS delete (new F()).getElement.caller:::true
+PASS delete (new F()).getElement["caller"]:::true
+PASS delete (new F()).getElement.arguments:::true
+PASS delete (new F()).getElement["arguments"]:::true
+arr
+PASS 'length,name':::'length,name'
+()=>{}
+PASS 'length,name':::'length,name'
+PASS arr.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS arr.hasOwnProperty("caller"):::false
+PASS arr.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(arr, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(arr, "arguments"):::undefined
+PASS delete arr.caller:::true
+PASS delete arr["caller"]:::true
+PASS delete arr.arguments:::true
+PASS delete arr["arguments"]:::true
+PASS (()=>{}).caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{}).arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{})["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{})["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{}).caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{}).arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{})["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{})["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (()=>{}).hasOwnProperty("caller"):::false
+PASS (()=>{}).hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((()=>{}), "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((()=>{}), "arguments"):::undefined
+PASS delete (()=>{}).caller:::true
+PASS delete (()=>{})["caller"]:::true
+PASS delete (()=>{}).arguments:::true
+PASS delete (()=>{})["arguments"]:::true
+PASS g.item.caller:::undefined
+PASS g.item.arguments:::undefined
+PASS (new G()).item.caller:::undefined
+PASS (new G()).item.arguments:::undefined
+PASS H.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS H.hasOwnProperty("caller"):::false
+PASS H.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(H, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(H, "arguments"):::undefined
+PASS delete H.caller:::true
+PASS delete H["caller"]:::true
+PASS delete H.arguments:::true
+PASS delete H["arguments"]:::true
+PASS h.caller():::"value"
+PASS h.arguments():::"value"
+h.caller
+PASS 'length,name,prototype':::'length,name,prototype'
+h.arguments
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS h.caller.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS h.caller.hasOwnProperty("caller"):::false
+PASS h.caller.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(h.caller, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(h.caller, "arguments"):::undefined
+PASS delete h.caller.caller:::true
+PASS delete h.caller["caller"]:::true
+PASS delete h.caller.arguments:::true
+PASS delete h.caller["arguments"]:::true
+PASS (new H()).caller():::"value"
+PASS (new H()).arguments():::"value"
+PASS (new H()).caller.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new H()).caller.hasOwnProperty("caller"):::false
+PASS (new H()).caller.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new H()).caller, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new H()).caller, "arguments"):::undefined
+PASS delete (new H()).caller.caller:::true
+PASS delete (new H()).caller["caller"]:::true
+PASS delete (new H()).caller.arguments:::true
+PASS delete (new H()).caller["arguments"]:::true
+J.gen
+PASS 'length,name,prototype':::'length,name,prototype'
+J.get
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS J.gen.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.gen.hasOwnProperty("caller"):::false
+PASS J.gen.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(J.gen, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(J.gen, "arguments"):::undefined
+PASS delete J.gen.caller:::true
+PASS delete J.gen["caller"]:::true
+PASS delete J.gen.arguments:::true
+PASS delete J.gen["arguments"]:::true
+PASS J.get.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS J.get.hasOwnProperty("caller"):::false
+PASS J.get.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(J.get, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(J.get, "arguments"):::undefined
+PASS delete J.get.caller:::true
+PASS delete J.get["caller"]:::true
+PASS delete J.get.arguments:::true
+PASS delete J.get["arguments"]:::true
+j.gen
+PASS 'length,name,prototype':::'length,name,prototype'
+j.get
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS j.gen.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.gen.hasOwnProperty("caller"):::false
+PASS j.gen.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(j.gen, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(j.gen, "arguments"):::undefined
+PASS delete j.gen.caller:::true
+PASS delete j.gen["caller"]:::true
+PASS delete j.gen.arguments:::true
+PASS delete j.gen["arguments"]:::true
+PASS j.get.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS j.get.hasOwnProperty("caller"):::false
+PASS j.get.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor(j.get, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor(j.get, "arguments"):::undefined
+PASS delete j.get.caller:::true
+PASS delete j.get["caller"]:::true
+PASS delete j.get.arguments:::true
+PASS delete j.get["arguments"]:::true
+(new J).gen
+PASS 'length,name,prototype':::'length,name,prototype'
+(new J).get
+PASS 'length,name,prototype':::'length,name,prototype'
+PASS (new J).gen.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).gen.hasOwnProperty("caller"):::false
+PASS (new J).gen.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new J).gen, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new J).gen, "arguments"):::undefined
+PASS delete (new J).gen.caller:::true
+PASS delete (new J).gen["caller"]:::true
+PASS delete (new J).gen.arguments:::true
+PASS delete (new J).gen["arguments"]:::true
+PASS (new J).get.caller:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get.arguments:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get["caller"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get["arguments"]:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get.caller = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get.arguments = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get["caller"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get["arguments"] = function () {}:::TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode.
+PASS (new J).get.hasOwnProperty("caller"):::false
+PASS (new J).get.hasOwnProperty("arguments"):::false
+PASS Object.getOwnPropertyDescriptor((new J).get, "caller"):::undefined
+PASS Object.getOwnPropertyDescriptor((new J).get, "arguments"):::undefined
+PASS delete (new J).get.caller:::true
+PASS delete (new J).get["caller"]:::true
+PASS delete (new J).get.arguments:::true
+PASS delete (new J).get["arguments"]:::true
+PASS successfullyParsed:::true
+
+TEST COMPLETE
+
@@ -2,7 +2,7 @@
 <html>
 <body>
 <script src="../resources/js-test-pre.js"></script>
-<script src="script-tests/class-method-and-constructor-properties.js"></script>
+<script src="script-tests/es6-function-properties.js"></script>
 <script src="../resources/js-test-post.js"></script>
 </body>
-</html>
+</html>
\ No newline at end of file
index 664988c..f56a943 100644 (file)
@@ -37,7 +37,7 @@ function f(a,b,c) {
 
   // DontDelete
   DontDeleteOK = !delete(f.arguments);
-  if (f.arguments == undefined || !f.hasOwnProperty("arguments"))
+  if (f.arguments == undefined || !f.__proto__.hasOwnProperty("arguments"))
     DontDeleteOK = false;
 
   // DontEnum
diff --git a/LayoutTests/js/non-strict-function-properties-expected.txt b/LayoutTests/js/non-strict-function-properties-expected.txt
new file mode 100644 (file)
index 0000000..792896b
--- /dev/null
@@ -0,0 +1,29 @@
+Test caller and arguments properties in function in non strict mode
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Object.getOwnPropertyNames(function () {}).length is 5
+PASS Object.getOwnPropertyNames(function () {}).includes("caller") is true
+PASS Object.getOwnPropertyNames(function () {}).includes("arguments") is true
+PASS (function(){}).hasOwnProperty("caller") is true
+PASS (function(){}).__proto__.hasOwnProperty("caller") is true
+PASS (function(){}).hasOwnProperty("arguments") is true
+PASS (function(){}).__proto__.hasOwnProperty("arguments") is true
+PASS typeof Object.getOwnPropertyDescriptor(foo, "arguments") is "object"
+PASS typeof Object.getOwnPropertyDescriptor(foo, "caller") is "object"
+PASS foo.caller is null
+PASS foo.arguments is null
+PASS foo.caller is null
+PASS foo.arguments is null
+PASS boo("abc")[0] is "abc"
+PASS boo("expected-value")[0] is "expected-value"
+PASS g(f) is g
+PASS doSetCaller(value, false) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode..
+PASS doSetCaller(value, true).__proto__.caller is value
+PASS doSetArguments(value, false) threw exception TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in strict mode..
+PASS doSetArguments(value, true).__proto__.arguments is value
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/non-strict-function-properties.html b/LayoutTests/js/non-strict-function-properties.html
new file mode 100644 (file)
index 0000000..96742dd
--- /dev/null
@@ -0,0 +1,8 @@
+<DOCTYPE html>
+<html>
+<body>
+<script src="../resources/js-test-pre.js"></script>
+<script src="script-tests/non-strict-function-properties.js"></script>
+<script src="../resources/js-test-post.js"></script>
+</body>
+</html>
index 28dfa52..769451f 100644 (file)
@@ -53,7 +53,7 @@ var expectedPropertyNamesSet = {
     "Object": "['assign', 'create', 'defineProperties', 'defineProperty', 'entries', 'freeze', 'getOwnPropertyDescriptor', 'getOwnPropertyDescriptors', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'values']",
     "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
     "Function": "['length', 'name', 'prototype']",
-    "Function.prototype": "['apply', 'bind', 'call', 'constructor', 'length', 'name', 'toString']",
+    "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']",
     "Array": "['from', 'isArray', 'length', 'name', 'of', 'prototype']",
     "Array.prototype": "['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']",
     "String": "['fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']",
index c35de26..0019f21 100644 (file)
@@ -91,9 +91,11 @@ shouldBe("var o = {foo: function a(a){'use strict'; return a+2; } }; o.foo(40)",
 
 // arguments/caller poisoning should be visible but not throw with 'in' & 'hasOwnProperty'.
 shouldBeTrue('"caller" in function(){"use strict"}');
-shouldBeTrue('(function(){"use strict";}).hasOwnProperty("caller")');
+shouldBeFalse('(function(){"use strict";}).hasOwnProperty("caller")');
+shouldBeTrue('(function(){"use strict";}).__proto__.hasOwnProperty("caller")');
 shouldBeTrue('"arguments" in function(){"use strict"}');
-shouldBeTrue('(function(){"use strict";}).hasOwnProperty("arguments")');
+shouldBeFalse('(function(){"use strict";}).hasOwnProperty("arguments")');
+shouldBeTrue('(function(){"use strict";}).__proto__.hasOwnProperty("arguments")');
  
 shouldBeSyntaxError("'use strict'; (function (){with(1){};})");
 shouldBeSyntaxError("'use strict'; (function (){var a; delete a;})");
@@ -176,14 +178,14 @@ shouldBeTrue("(function (){'use strict';  var local; (function (){local;})(); ar
 shouldBeTrue("'use strict'; (function (){var a = true; eval('var a = false'); return a; })()");
 shouldBeTrue("(function (){var a = true; eval('\"use strict\"; var a = false'); return a; })()");
 
-shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'arguments').value; })()");
-shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f, 'caller').value; })()");
+shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'arguments').value; })()");
+shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(f.__proto__, 'caller').value; })()");
 shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').value; })()");
 shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller').value; })()");
 shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'caller'); return descriptor.get === descriptor.set; })()");
 shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(arguments, 'callee'); return descriptor.get === descriptor.set; })()");
-shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'caller'); return descriptor.get === descriptor.set; })()");
-shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f, 'arguments'); return descriptor.get === descriptor.set; })()");
+shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })()");
+shouldBeTrue("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'arguments'); return descriptor.get === descriptor.set; })()");
 shouldBeTrue("'use strict'; (function f() { for(var i in this); })(); true;")
 
 shouldBeSyntaxError("'use strict'\u033b");
@@ -210,4 +212,4 @@ aGlobal = false;
 shouldBeTrue("(function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;");
 
 // Make sure this doesn't crash!
-shouldBe('String(Object.getOwnPropertyDescriptor(function() { "use strict"; }, "caller").get)', "'function () {\\n    [native code]\\n}'");
+shouldBe('String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get)', "'function () {\\n    [native code]\\n}'");
\ No newline at end of file
diff --git a/LayoutTests/js/script-tests/class-method-and-constructor-properties.js b/LayoutTests/js/script-tests/class-method-and-constructor-properties.js
deleted file mode 100644 (file)
index 6c919a2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-
-description('Tests for ES6 class method and constructor properties');
-
-function shouldThrow(s, message) {
-    var threw = false;
-    try {
-        eval(s);
-    } catch(e) {
-        threw = true;
-        if (!message || e.toString() === eval(message))
-            testPassed(s + ":::" + e.toString());
-        else
-            testFailed(s);
-    }
-    if (!threw)
-        testFailed(s);
-}
-
-function shouldBe(a, b) {
-    var r1 = eval(a);
-    var r2 = eval(b)
-    if (r1 === r2)
-        testPassed(a + ":::" + b);
-    else
-        testFailed(r1 + ":::" + r2);
-}
-
-class A { };
-class B extends A { };
-class C extends A { constructor () {super();}}
-class D { constructor () {}}
-class E { getItem() { return 'text';} }
-class F extends E { getElement() { return 'text'}}
-class G extends E { get item() { return 'text'} }
-
-shouldThrow('(new A()).constructor.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new A()).constructor.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new B()).constructor.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new B()).constructor.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new C()).constructor.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new C()).constructor.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new D()).constructor.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new D()).constructor.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new E()).getItem.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new E()).getItem.arguments', '');
-shouldThrow('(new F()).getItem.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new F()).getItem.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new F()).getElement.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new F()).getElement.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-
-shouldBe('(new G()).item.caller', 'undefined');
-shouldBe('(new G()).item.arguments', 'undefined');
-
-class H {
-  caller() { return 'value'; }
-  arguments() { return 'value'; }
-}
-
-shouldThrow('H.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('H.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-
-shouldBe('(new H()).caller()', '"value"');
-shouldBe('(new H()).arguments()', '"value"');
-
-shouldThrow('(new H()).caller.caller', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-shouldThrow('(new H()).caller.arguments', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
-
-
-var successfullyParsed = true;
index 6643ced..af7ddcb 100644 (file)
@@ -10,6 +10,7 @@ shouldBe("setterValue = undefined; class A { set get(x) { setterValue = x; } };
 shouldBe("setterValue = undefined; class A { set set(x) { setterValue = x; } }; (new A).set = 7; setterValue", "7");
 
 debug('');
+var staticMethodValue = 'value';
 debug('Static methods');
 shouldBe("class A { static 0.1() { return 101; } }; A[0.1]()", "101");
 shouldBe("class A { static get() { return 102; } }; A.get()", "102");
@@ -18,6 +19,32 @@ shouldBe("class A { static get get() { return 104; } }; A.get", "104");
 shouldBe("class A { static get set() { return 105; } }; A.set", "105");
 shouldBe("setterValue = undefined; class A { static set get(x) { setterValue = x; } }; A.get = 106; setterValue", "106");
 shouldBe("setterValue = undefined; class A { static set set(x) { setterValue = x; } }; A.set = 107; setterValue", "107");
+shouldNotThrow("class X {static arguments() {}}");
+shouldNotThrow("class X {static caller() {}}");
+shouldBe("(class X {static arguments() {return staticMethodValue;}}).arguments()", "staticMethodValue");
+shouldBe("(class X {static caller() {return staticMethodValue;}}).caller()", "staticMethodValue");
+shouldBe("(class X {static arguments() {return staticMethodValue;}}).hasOwnProperty('arguments')", "true");
+shouldBe("(class X {static caller() {return staticMethodValue;}}).hasOwnProperty('caller')", "true");
+shouldNotThrow("class X {static get arguments() {}}");
+shouldNotThrow("class X {static get caller() {}}");
+shouldBe("(class X {static get arguments() {return staticMethodValue;}}).arguments", "staticMethodValue");
+shouldBe("(class X {static get caller() {return staticMethodValue;}}).caller", "staticMethodValue");
+shouldBe("(class X {static get arguments() {return staticMethodValue;}}).hasOwnProperty('arguments')", "true");
+shouldBe("(class X {static get caller() {return staticMethodValue;}}).hasOwnProperty('caller')", "true");
+shouldThrow('class X {static caller() {return staticMethodValue;}};X.arguments = function(){}', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
+shouldThrow('class X {static arguments() {return staticMethodValue;}}; X.caller = function(){}', '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."');
+shouldBe('class X {static caller() {return "";}} X.caller = function(){ return staticMethodValue; };X.caller()', 'staticMethodValue');
+shouldBe('class X {static arguments() {return "";}}; X.arguments = function(){ return staticMethodValue; };X.arguments()', 'staticMethodValue');
+shouldBe('class X {static caller() {return "";}} X["caller"] = function(){ return staticMethodValue; };X.caller()', 'staticMethodValue');
+shouldBe('class X {static arguments() {return "";}}; X["arguments"] = function(){ return staticMethodValue; };X.arguments()', 'staticMethodValue');
+shouldBe('class X {static *caller() {yield staticMethodValue;}}; X.caller().next().value', 'staticMethodValue');
+shouldBe('class X {static *arguments() {yield staticMethodValue;}}; X.arguments().next().value', 'staticMethodValue');
+shouldBe('class X {static *caller() {yield;}}; X["caller"] = function*(){yield staticMethodValue;}; X.caller().next().value', 'staticMethodValue');
+shouldBe('class X {static *arguments() {yield;}}; X["arguments"] = function*(){yield staticMethodValue;}; X.arguments().next().value', 'staticMethodValue');
+shouldBe('class X {*caller() {yield staticMethodValue;}}; let x = new X; x.caller().next().value', 'staticMethodValue');
+shouldBe('class X {*arguments() {yield staticMethodValue;}}; let x = new X; x.arguments().next().value', 'staticMethodValue');
+shouldBe('class X {*caller() {yield;}}; let x = new X; x["caller"] = function*(){yield staticMethodValue;}; x.caller().next().value', 'staticMethodValue');
+shouldBe('class X {*arguments() {yield;}}; let x = new X; x["arguments"] = function*(){yield staticMethodValue;}; x.arguments().next().value', 'staticMethodValue');
 
 debug('');
 debug('Instance methods with computed names');
diff --git a/LayoutTests/js/script-tests/es6-function-properties.js b/LayoutTests/js/script-tests/es6-function-properties.js
new file mode 100644 (file)
index 0000000..5c4d885
--- /dev/null
@@ -0,0 +1,191 @@
+description('Tests for ES6 class method and constructor properties');
+
+function shouldThrow(s, message) {
+    var threw = false;
+    try {
+        eval(s);
+    } catch(e) {
+        threw = true;
+        if (!message || e.toString() === eval(message))
+            testPassed(s + ":::" + e.toString());
+        else
+            testFailed(s);
+    }
+    if (!threw)
+        testFailed(s);
+}
+
+function shouldBe(a, b) {
+    var r1 = eval(a);
+    var r2 = eval(b)
+    if (r1 === r2)
+        testPassed(a + ":::" + b);
+    else
+        testFailed(r1 + ":::" + r2);
+}
+
+ var typeErrorText = '"TypeError: \'arguments\', \'callee\', and \'caller\' cannot be accessed in strict mode."';
+
+class A { };
+class B extends A { };
+class C extends A { constructor () {super();}}
+class D { constructor () {}}
+class E { getItem() { return 'text';} }
+class F extends E { getElement() { return 'text'}}
+class G extends E { get item() { return 'text'} }
+
+var wrongPropertyInAList = '';
+
+var check = function (text) {
+    shouldThrow(text + '.caller', typeErrorText);
+    shouldThrow(text + '.arguments', typeErrorText);
+    shouldThrow(text + '["caller"]', typeErrorText);
+    shouldThrow(text + '["arguments"]', typeErrorText);
+    shouldThrow(text + '.caller = function () {}', typeErrorText);
+    shouldThrow(text + '.arguments = function () {}', typeErrorText);
+    shouldThrow(text + '["caller"] = function () {}', typeErrorText);
+    shouldThrow(text + '["arguments"] = function () {}', typeErrorText);
+
+    shouldBe(text + '.hasOwnProperty("caller")', 'false');
+    shouldBe(text + '.hasOwnProperty("arguments")', 'false');
+    var object = eval(text);
+
+    for (var propertyName in object) {
+        wrongPropertyInAList = propertyName === 'caller' || propertyName === 'arguments';
+        if (wrongPropertyInAList)
+           shouldBe('wrongPropertyInAList', 'false');
+    }
+
+    shouldBe('Object.getOwnPropertyDescriptor(' + text + ', "caller")', 'undefined');
+    shouldBe('Object.getOwnPropertyDescriptor(' + text + ', "arguments")', 'undefined');
+    shouldBe('delete ' + text +'.caller', true);
+    shouldBe('delete ' + text +'["caller"]', true);
+    shouldBe('delete ' + text +'.arguments', true);
+    shouldBe('delete ' + text +'["arguments"]', true);
+}
+
+var checkProperties = function (value, expected, text) { 
+    debug(text);
+    var properties = Object.getOwnPropertyNames(value).toString();
+    shouldBe("'" + properties + "'", "'" + expected + "'");
+};
+
+var a = new A;
+
+checkProperties(a.constructor, "length,name,prototype", "a.constructor");
+checkProperties((new A()).constructor, "length,name,prototype", "(new A()).constructor");
+
+check('a.constructor');
+check('a.constructor');
+check('(new A()).constructor');
+
+var b = new B;
+
+checkProperties(b.constructor, "length,name,prototype", "b.constructor");
+checkProperties((new B()).constructor, "length,name,prototype", "(new B()).constructor");
+
+check('b.constructor');
+check('(new B()).constructor');
+
+var c = new C;
+
+checkProperties(c.constructor, "length,name,prototype", "c.constructor");
+checkProperties((new C()).constructor, "length,name,prototype", "(new C()).constructor");
+
+check('c.constructor');
+check('(new C()).constructor');
+
+var d = new D;
+
+checkProperties(d.constructor, "length,name,prototype", "c.constructor");
+checkProperties((new D()).constructor, "length,name,prototype", "(new D()).constructor");
+
+check('d.constructor');
+check('(new D()).constructor');
+
+var e = new E;
+
+checkProperties(e.constructor, "length,name,prototype", "e.constructor");
+checkProperties((new E()).getItem, "length,name,prototype", "(new E()).getItem");
+
+check('e.constructor');
+check('(new E()).getItem');
+
+var f = new F;
+
+checkProperties(f.getItem, "length,name,prototype", "f.getItem");
+checkProperties(f.getElement, "length,name,prototype", "f.getElement");
+
+check('f.getItem');
+check('f.getElement');
+
+checkProperties((new F()).getItem, "length,name,prototype", "(new F()).getItem");
+checkProperties((new F()).getElement, "length,name,prototype", "(new F()).getElement");
+
+check('(new F()).getItem');
+check('(new F()).getElement');
+
+var arr = ()=>{};
+
+checkProperties(arr, "length,name", "arr");
+checkProperties((()=>{}), "length,name", "()=>{}");
+
+check('arr');
+check('(()=>{})');
+
+var g = new G;
+shouldBe('g.item.caller', 'undefined');
+shouldBe('g.item.arguments', 'undefined');
+shouldBe('(new G()).item.caller', 'undefined');
+shouldBe('(new G()).item.arguments', 'undefined');
+
+class H {
+    caller() { return 'value'; }
+    arguments() { return 'value'; }
+}
+
+check('H');
+
+var h = new H;
+
+shouldBe('h.caller()', '"value"');
+shouldBe('h.arguments()', '"value"');
+
+checkProperties(h.caller, "length,name,prototype", "h.caller");
+checkProperties(h.arguments, "length,name,prototype", "h.arguments");
+
+check('h.caller');
+
+shouldBe('(new H()).caller()', '"value"');
+shouldBe('(new H()).arguments()', '"value"');
+
+check('(new H()).caller', "length,name,prototype");
+
+class J {
+    *gen() {yield;}
+    static *gen() {yield;}
+    *get() {}
+    static *get() {}
+}
+
+checkProperties(J.gen, "length,name,prototype", "J.gen");
+checkProperties(J.get, "length,name,prototype", "J.get");
+
+check('J.gen');
+check('J.get');
+
+var j = new J;
+
+checkProperties(j.gen, "length,name,prototype", "j.gen");
+checkProperties(j.get, "length,name,prototype", "j.get");
+
+check('j.gen');
+check('j.get');
+
+checkProperties((new J).gen, "length,name,prototype", "(new J).gen");
+checkProperties((new J).get, "length,name,prototype", "(new J).get");
+
+check('(new J).gen');
+check('(new J).get');
+
+var successfullyParsed = true;
diff --git a/LayoutTests/js/script-tests/non-strict-function-properties.js b/LayoutTests/js/script-tests/non-strict-function-properties.js
new file mode 100644 (file)
index 0000000..d3e0e77
--- /dev/null
@@ -0,0 +1,65 @@
+description('Test caller and arguments properties in function in non strict mode');
+
+function foo() {
+    return 1;
+}
+
+shouldBe('Object.getOwnPropertyNames(function () {}).length','5');
+
+shouldBeTrue('Object.getOwnPropertyNames(function () {}).includes("caller")');
+shouldBeTrue('Object.getOwnPropertyNames(function () {}).includes("arguments")');
+
+shouldBeTrue('(function(){}).hasOwnProperty("caller")');
+shouldBeTrue('(function(){}).__proto__.hasOwnProperty("caller")');
+
+shouldBeTrue('(function(){}).hasOwnProperty("arguments")');
+shouldBeTrue('(function(){}).__proto__.hasOwnProperty("arguments")');
+
+shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "arguments")', '"object"');
+shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "caller")', '"object"');
+
+shouldBe('foo.caller', 'null');
+shouldBe('foo.arguments', 'null');
+
+foo.caller = 10;
+foo.arguments = 10;
+
+shouldBe('foo.caller', 'null');
+shouldBe('foo.arguments', 'null');
+
+var boo = function () { return boo.arguments; };
+
+shouldBe('boo("abc")[0]','"abc"');
+
+boo.arguments = 'not-expected-value';
+shouldBe('boo("expected-value")[0]','"expected-value"');
+
+var f = function () { return f.caller;  };
+var g = function (cb) { return cb(); };
+
+shouldBe('g(f)','g');
+
+var doSetCaller = function (value, doDelete) {
+       var f = function () {};
+       if (doDelete)
+               delete f.__proto__.caller;
+       f.__proto__.caller = value;
+       return f;
+};
+
+var value = "property-value";
+
+shouldThrow("doSetCaller(value, false)", "'TypeError: \\'arguments\\', \\'callee\\', and \\'caller\\' cannot be accessed in strict mode.'");
+shouldBe("doSetCaller(value, true).__proto__.caller", "value");
+
+
+var doSetArguments = function (value, doDelete) {
+       var f = function () {};
+       if (doDelete)
+               delete f.__proto__.arguments;
+       f.__proto__.arguments = value;
+       return f;
+};
+
+shouldThrow("doSetArguments(value, false)", "'TypeError: \\'arguments\\', \\'callee\\', and \\'caller\\' cannot be accessed in strict mode.'");
+shouldBe("doSetArguments(value, true).__proto__.arguments", "value");
index 734a690..a54ea09 100644 (file)
@@ -12,8 +12,8 @@ function strictArgumentsFunction1()
 }
 var strictArguments1 = strictArgumentsFunction1();
 var boundFunction1 = strictArgumentsFunction1.bind();
-var functionCaller1 = getter(strictArgumentsFunction1, "caller");
-var functionArguments1 = getter(strictArgumentsFunction1, "arguments");
+var functionCaller1 = getter(strictArgumentsFunction1.__proto__, "caller");
+var functionArguments1 = getter(strictArgumentsFunction1.__proto__, "arguments");
 var argumentsCaller1 = getter(strictArguments1, "caller");
 var argumentsCallee1 = getter(strictArguments1, "callee");
 var boundCaller1 = getter(boundFunction1, "caller");
@@ -26,8 +26,8 @@ function strictArgumentsFunction2()
 }
 var strictArguments2 = strictArgumentsFunction2();
 var boundFunction2 = strictArgumentsFunction2.bind();
-var functionCaller2 = getter(strictArgumentsFunction2, "caller");
-var functionArguments2 = getter(strictArgumentsFunction2, "arguments");
+var functionCaller2 = getter(strictArgumentsFunction2.__proto__, "caller");
+var functionArguments2 = getter(strictArgumentsFunction2.__proto__, "arguments");
 var argumentsCaller2 = getter(strictArguments2, "caller");
 var argumentsCallee2 = getter(strictArguments2, "callee");
 var boundCaller2 = getter(boundFunction2, "caller");
index 4be1a74..cbf5a90 100644 (file)
@@ -1,3 +1,39 @@
+2016-09-12  Skachkov Oleksandr  <gskachkov@gmail.com>
+
+        ES6: Classes: Should be allowed to create a static method with name "arguments"
+        https://bugs.webkit.org/show_bug.cgi?id=152985
+
+        Reviewed by Keith Miller.
+
+        Current patch covered 16.2 Forbidden Extensions - first topic 
+        (https://tc39.github.io/ecma262/#sec-forbidden-extensions) ECMAScript Functions 
+        should not have own properties named "caller" or "arguments".
+        Also added possibility to declare static methods and getters with 
+        name 'arguments' and 'caller' for classes. i.e.:
+        class A { static arguments() { return 'value'; } }
+        A.arguments() === 'value';
+        To implement this patch 'caller' and 'arguments' were put to the FunctionPrototype
+        object. Also was changed approach to init throwTypeErrorArgumentsCalleeAndCallerGetterSetter
+        property from Lazy to common because it necessary to use execState during init of the accessors 
+        properties.
+
+        * runtime/Executable.h:
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::initRestrictedProperties):
+        (JSC::FunctionPrototype::addFunctionProperties): Deleted.
+        * runtime/FunctionPrototype.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getOwnPropertySlot):
+        (JSC::JSFunction::getOwnNonIndexPropertyNames):
+        (JSC::JSFunction::put):
+        (JSC::JSFunction::deleteProperty):
+        (JSC::JSFunction::defineOwnProperty):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::throwTypeErrorArgumentsCalleeAndCallerGetterSetter):
+
 2016-09-12  Filip Pizlo  <fpizlo@apple.com>
 
         MarkedBlock should be able to use flipIfNecessary() as the "I'm not empty" trigger
index bd2c144..ac8ab6f 100644 (file)
@@ -654,6 +654,8 @@ public:
     bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
     bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }
     bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }
+    bool isGenerator() const { return parseMode() == SourceParseMode::GeneratorBodyMode || parseMode() == SourceParseMode::GeneratorWrapperFunctionMode; }
+    bool isES6Function() const { return isClassConstructorFunction() || isArrowFunction() || isGenerator() || parseMode() == SourceParseMode::MethodMode;}
     DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); }
     bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
     const Identifier& name() { return m_unlinkedExecutable->name(); }
index ce55e47..868b048 100644 (file)
 
 #include "BuiltinExecutables.h"
 #include "BuiltinNames.h"
+#include "ClonedArguments.h"
 #include "Error.h"
+#include "GetterSetter.h"
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSFunction.h"
+#include "JSGlobalObjectFunctions.h"
 #include "JSString.h"
 #include "JSStringBuilder.h"
 #include "Interpreter.h"
@@ -64,6 +67,14 @@ void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* g
     *hasInstanceSymbolFunction = putDirectBuiltinFunction(vm, globalObject, vm.propertyNames->hasInstanceSymbol, functionPrototypeSymbolHasInstanceCodeGenerator(vm), DontDelete | ReadOnly | DontEnum);
     putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->bind, functionPrototypeBindCodeGenerator(vm), DontEnum);
 }
+    
+void FunctionPrototype::initRestrictedProperties(ExecState* exec, JSGlobalObject* globalObject)
+{
+    VM& vm = exec->vm();
+    GetterSetter* errorGetterSetter = globalObject->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();
+    putDirectAccessor(exec, vm.propertyNames->caller, errorGetterSetter, DontEnum | Accessor);
+    putDirectAccessor(exec, vm.propertyNames->arguments, errorGetterSetter, DontEnum | Accessor);
+}
 
 static EncodedJSValue JSC_HOST_CALL callFunctionPrototype(ExecState*)
 {
index abe533a..9dad74c 100644 (file)
@@ -38,6 +38,8 @@ public:
 
     void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction, JSFunction** hasInstanceSymbolFunction);
 
+    void initRestrictedProperties(ExecState*, JSGlobalObject*);
+
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     {
         return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
index 8d20085..00de8b6 100644 (file)
@@ -371,32 +371,18 @@ bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyN
         slot.setValue(thisObject, attributes, thisObject->getDirect(offset), offset);
     }
 
-    if (propertyName == vm.propertyNames->arguments) {
-        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) {
-            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
-            if (!result) {
-                GetterSetter* errorGetterSetter = thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();
-                thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor);
-                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
-                ASSERT(result);
-            }
-            return result;
-        }
+    if (propertyName == exec->propertyNames().arguments) {
+        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isES6Function())
+            return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+
         slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, argumentsGetter);
         return true;
     }
 
-    if (propertyName == vm.propertyNames->caller) {
-        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) {
-            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
-            if (!result) {
-                GetterSetter* errorGetterSetter = thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();
-                thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor);
-                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
-                ASSERT(result);
-            }
-            return result;
-        }
+    if (propertyName == exec->propertyNames().caller) {
+        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isES6Function())
+            return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
+
         slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, callerGetter);
         return true;
     }
@@ -415,8 +401,10 @@ void JSFunction::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec,
         PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
         thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, exec, vm.propertyNames->prototype, slot);
 
-        propertyNames.add(vm.propertyNames->arguments);
-        propertyNames.add(vm.propertyNames->caller);
+        if (!thisObject->jsExecutable()->isStrictMode() && !thisObject->jsExecutable()->isES6Function()) {
+            propertyNames.add(vm.propertyNames->arguments);
+            propertyNames.add(vm.propertyNames->caller);
+        }
         if (!thisObject->hasReifiedLength())
             propertyNames.add(vm.propertyNames->length);
         if (!thisObject->hasReifiedName())
@@ -453,7 +441,8 @@ bool JSFunction::put(JSCell* cell, ExecState* exec, PropertyName propertyName, J
         scope.release();
         return Base::put(thisObject, exec, propertyName, value, dontCache);
     }
-    if (thisObject->jsExecutable()->isStrictMode() && (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller)) {
+
+    if ((thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isES6Function()) && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {
         // This will trigger the property to be reified, if this is not already the case!
         bool okay = thisObject->hasProperty(exec, propertyName);
         ASSERT_UNUSED(okay, okay);
@@ -479,10 +468,15 @@ bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prop
         // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
         VM& vm = exec->vm();
         FunctionExecutable* executable = thisObject->jsExecutable();
-        if (propertyName == vm.propertyNames->arguments
-            || (propertyName == vm.propertyNames->prototype && !executable->isArrowFunction())
-            || propertyName == vm.propertyNames->caller)
+        bool isES6OrStrictMode = executable->isStrictMode() || executable->isES6Function();
+        if ((propertyName == exec->propertyNames().arguments && !isES6OrStrictMode)
+            || (propertyName == exec->propertyNames().prototype && !executable->isArrowFunction())
+            || (propertyName == exec->propertyNames().caller && !isES6OrStrictMode))
             return false;
+        
+        if ((propertyName == exec->propertyNames().arguments && isES6OrStrictMode)
+            || (propertyName == exec->propertyNames().caller && isES6OrStrictMode))
+            return true;
 
         thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName);
     }
@@ -512,16 +506,24 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa
     }
 
     bool valueCheck;
-    if (propertyName == vm.propertyNames->arguments) {
-        if (thisObject->jsExecutable()->isStrictMode()) {
+    if (propertyName == exec->propertyNames().arguments) {
+        if (thisObject->jsExecutable()->isClass()) {
+            thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName);
+            return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+        }
+        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isES6Function()) {
             PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
             if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
                 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor);
             return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
         }
         valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveArguments(exec, thisObject));
-    } else if (propertyName == vm.propertyNames->caller) {
-        if (thisObject->jsExecutable()->isStrictMode()) {
+    } else if (propertyName == exec->propertyNames().caller) {
+        if (thisObject->jsExecutable()->isClass()) {
+            thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName);
+            return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+        }
+        if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isES6Function()) {
             PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry);
             if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
                 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor);
index d74292d..65b2c0a 100644 (file)
@@ -409,14 +409,7 @@ void JSGlobalObject::init(VM& vm)
             getterSetter->setSetter(init.vm, init.owner, thrower);
             init.set(getterSetter);
         });
-    m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.initLater(
-        [] (const Initializer<GetterSetter>& init) {
-            JSFunction* thrower = JSFunction::create(init.vm, init.owner, 0, String(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);
-            GetterSetter* getterSetter = GetterSetter::create(init.vm, init.owner);
-            getterSetter->setGetter(init.vm, init.owner, thrower);
-            getterSetter->setSetter(init.vm, init.owner, thrower);
-            init.set(getterSetter);
-        });
+
     m_nullGetterFunction.set(vm, this, NullGetterFunction::create(vm, NullGetterFunction::createStructure(vm, this, m_functionPrototype.get())));
     m_nullSetterFunction.set(vm, this, NullSetterFunction::create(vm, NullSetterFunction::createStructure(vm, this, m_functionPrototype.get())));
     m_objectPrototype.set(vm, this, ObjectPrototype::create(vm, this, ObjectPrototype::createStructure(vm, this, jsNull())));
@@ -426,6 +419,14 @@ void JSGlobalObject::init(VM& vm)
     m_objectPrototype->putDirectNonIndexAccessor(vm, vm.propertyNames->underscoreProto, protoAccessor, Accessor | DontEnum);
     m_functionPrototype->structure()->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
     m_objectStructureForObjectConstructor.set(vm, this, vm.prototypeMap.emptyObjectStructureForPrototype(m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
+    
+    JSFunction* thrower = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);
+    GetterSetter* getterSetter = GetterSetter::create(vm, this);
+    getterSetter->setGetter(vm, this, thrower);
+    getterSetter->setSetter(vm, this, thrower);
+    m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.set(vm, this, getterSetter);
+    
+    m_functionPrototype->initRestrictedProperties(exec, this);
 
     m_speciesGetterSetter.set(vm, this, GetterSetter::create(vm, this));
     m_speciesGetterSetter->setGetter(vm, this, JSFunction::createBuiltinFunction(vm, globalOperationsSpeciesGetterCodeGenerator(vm), this, "get [Symbol.species]"));
@@ -1072,7 +1073,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_newPromiseCapabilityFunction);
     visitor.append(&thisObject->m_functionProtoHasInstanceSymbolFunction);
     thisObject->m_throwTypeErrorGetterSetter.visit(visitor);
-    thisObject->m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.visit(visitor);
+    visitor.append(&thisObject->m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter);
     visitor.append(&thisObject->m_moduleLoader);
 
     visitor.append(&thisObject->m_objectPrototype);
index 24d420d..c07e642 100644 (file)
@@ -247,7 +247,7 @@ public:
     WriteBarrier<JSObject> m_regExpProtoSymbolReplace;
     WriteBarrier<JSObject> m_regExpProtoGlobalGetter;
     WriteBarrier<JSObject> m_regExpProtoUnicodeGetter;
-    LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter;
+    WriteBarrier<GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter;
 
     WriteBarrier<JSModuleLoader> m_moduleLoader;
 
@@ -493,7 +493,7 @@ public:
     JSObject* regExpProtoUnicodeGetter() const { return m_regExpProtoUnicodeGetter.get(); }
     GetterSetter* throwTypeErrorArgumentsCalleeAndCallerGetterSetter()
     {
-        return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get(this);
+        return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get();
     }
     
     JSModuleLoader* moduleLoader() const { return m_moduleLoader.get(); }