Diff
Modified: trunk/JSTests/ChakraCore/test/strict/19.function.baseline (280288 => 280289)
--- trunk/JSTests/ChakraCore/test/strict/19.function.baseline 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/ChakraCore/test/strict/19.function.baseline 2021-07-25 22:32:20 UTC (rev 280289)
@@ -2,17 +2,5 @@
Return: function.caller set
Return: function.arguments get
Return: function.arguments get
-Test5.caller:configurable : false
-Test5.caller:enumerable : false
-Test5.caller:writable : false
-Test5.caller:getter : undefined
-Test5.caller:setter : undefined
-Test5.caller:value : null
-Return: function.caller get
-Test6.arguments:configurable : false
-Test6.arguments:enumerable : false
-Test6.arguments:writable : false
-Test6.arguments:getter : undefined
-Test6.arguments:setter : undefined
-Test6.arguments:value : [object Arguments]
-Return: function.arguments get
+Exception: function.caller get TypeError
+Exception: function.arguments get TypeError
Modified: trunk/JSTests/ChakraCore/test/strict/22.callerCalleeArguments.baseline-jsc (280288 => 280289)
--- trunk/JSTests/ChakraCore/test/strict/22.callerCalleeArguments.baseline-jsc 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/ChakraCore/test/strict/22.callerCalleeArguments.baseline-jsc 2021-07-25 22:32:20 UTC (rev 280289)
@@ -2,19 +2,19 @@
hasOwnProperty(caller): false
var foo = function(){};(function(){echo("hasOwnProperty(caller): ", foo.hasOwnProperty("caller"));})();
-hasOwnProperty(caller): true
+hasOwnProperty(caller): false
var foo = function(){};(function(){"use strict";echo("hasOwnProperty(caller): ", foo.hasOwnProperty("caller"));})();
-hasOwnProperty(caller): true
+hasOwnProperty(caller): false
(function(){echo("hasOwnProperty(callee): ", arguments.hasOwnProperty("callee"));})();
hasOwnProperty(callee): true
var foo = function(){};(function(){echo("hasOwnProperty(arguments): ", foo.hasOwnProperty("arguments"));})();
-hasOwnProperty(arguments): true
+hasOwnProperty(arguments): false
var foo = function(){};(function(){"use strict";echo("hasOwnProperty(arguments): ", foo.hasOwnProperty("arguments"));})();
-hasOwnProperty(arguments): true
+hasOwnProperty(arguments): false
(function(){arguments.caller;})();
@@ -33,7 +33,6 @@
var foo = function(){};(function(){foo.caller = 0;})();
var foo = function(){};(function(){"use strict";foo.caller = 0;})();
-TypeError: Attempted to assign to readonly property.
(function(){arguments.callee = 0;})();
@@ -40,34 +39,33 @@
var foo = function(){};(function(){foo.arguments = 0;})();
var foo = function(){};(function(){"use strict";foo.arguments = 0;})();
-TypeError: Attempted to assign to readonly property.
(function(){Object.defineProperty(arguments, "caller", {value: 0});})();
var foo = function(){};(function(){Object.defineProperty(foo, "caller", {value: 0});})();
-TypeError: Attempting to change value of a readonly property.
var foo = function(){};(function(){"use strict";Object.defineProperty(foo, "caller", {value: 0});})();
-TypeError: Attempting to change value of a readonly property.
(function(){Object.defineProperty(arguments, "callee", {value: 0});})();
var foo = function(){};(function(){Object.defineProperty(foo, "arguments", {value: 0});})();
-TypeError: Attempting to change value of a readonly property.
var foo = function(){};(function(){"use strict";Object.defineProperty(foo, "arguments", {value: 0});})();
-TypeError: Attempting to change value of a readonly property.
(function(){var descriptor = Object.getOwnPropertyDescriptor(arguments, "caller");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
TypeError: undefined is not an object (evaluating 'descriptor.hasOwnProperty')
var foo = function(){};(function(){var descriptor = Object.getOwnPropertyDescriptor(foo, "caller");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
+TypeError: undefined is not an object (evaluating 'descriptor.hasOwnProperty')
var foo = function(){};(function(){"use strict";var descriptor = Object.getOwnPropertyDescriptor(foo, "caller");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
+TypeError: undefined is not an object (evaluating 'descriptor.hasOwnProperty')
(function(){var descriptor = Object.getOwnPropertyDescriptor(arguments, "callee");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
var foo = function(){};(function(){var descriptor = Object.getOwnPropertyDescriptor(foo, "arguments");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
+TypeError: undefined is not an object (evaluating 'descriptor.hasOwnProperty')
var foo = function(){};(function(){"use strict";var descriptor = Object.getOwnPropertyDescriptor(foo, "arguments");if(descriptor.hasOwnProperty("get")) safeCall(descriptor.get);if(descriptor.hasOwnProperty("set")) safeCall(descriptor.set);})();
+TypeError: undefined is not an object (evaluating 'descriptor.hasOwnProperty')
Modified: trunk/JSTests/ChangeLog (280288 => 280289)
--- trunk/JSTests/ChangeLog 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/ChangeLog 2021-07-25 22:32:20 UTC (rev 280289)
@@ -1,3 +1,23 @@
+2021-07-25 Alexey Shvayka <[email protected]>
+
+ Partly implement Function.prototype.{caller,arguments} reflection proposal
+ https://bugs.webkit.org/show_bug.cgi?id=158116
+
+ Reviewed by Yusuke Suzuki.
+
+ * ChakraCore/test/strict/19.function.baseline:
+ * ChakraCore/test/strict/22.callerCalleeArguments.baseline-jsc:
+ * microbenchmarks/function-prototype-get.js: Added.
+ * microbenchmarks/reflect-own-keys-function.js: Added.
+ * stress/for-in-shadow-non-enumerable.js:
+ * stress/function-hidden-as-caller.js:
+ * stress/has-own-property-arguments.js:
+ * stress/object-assign-fast-path.js:
+ * stress/put-to-proto-chain-overrides-put.js:
+ * stress/reflect-set.js:
+ * test262/config.yaml: Skip 3 test cases that are now incorrect.
+ * test262/expectations.yaml: Mark 2 test cases as passing.
+
2021-07-23 Yusuke Suzuki <[email protected]>
[JSC] Add Speedometer2 jQuery-TodoMVC RegExp microbenchmark
Added: trunk/JSTests/microbenchmarks/function-prototype-get.js (0 => 280289)
--- trunk/JSTests/microbenchmarks/function-prototype-get.js (rev 0)
+++ trunk/JSTests/microbenchmarks/function-prototype-get.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -0,0 +1,7 @@
+(function() {
+ var prototype;
+ for (var i = 0; i < 2e5; ++i)
+ prototype = (function() {}).prototype;
+ if (!prototype)
+ throw new Error("Bad assertion!");
+})();
Added: trunk/JSTests/microbenchmarks/reflect-own-keys-function.js (0 => 280289)
--- trunk/JSTests/microbenchmarks/reflect-own-keys-function.js (rev 0)
+++ trunk/JSTests/microbenchmarks/reflect-own-keys-function.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -0,0 +1,9 @@
+noInline(Reflect.ownKeys);
+
+(function() {
+ var keys;
+ for (var i = 0; i < 1e5; ++i)
+ keys = Reflect.ownKeys(function() {});
+ if (!keys)
+ throw new Error("Bad assertion!");
+})();
Modified: trunk/JSTests/stress/for-in-shadow-non-enumerable.js (280288 => 280289)
--- trunk/JSTests/stress/for-in-shadow-non-enumerable.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/for-in-shadow-non-enumerable.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -28,7 +28,7 @@
{
name: "Function (non-strict)",
createObject: () => function() {},
- dontEnumKeys: ["arguments", "caller", "length", "name", "prototype"],
+ dontEnumKeys: ["length", "name", "prototype"],
},
{
name: "RegExp",
Modified: trunk/JSTests/stress/function-hidden-as-caller.js (280288 => 280289)
--- trunk/JSTests/stress/function-hidden-as-caller.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/function-hidden-as-caller.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -3,11 +3,13 @@
throw new Error(`Bad value: ${actual} (${testInfo})`);
}
+const functionPrototypeCallerGetter = Object.getOwnPropertyDescriptor(Function.prototype, "caller").get;
+
let callerViaGet;
let callerViaGetOwnProperty;
function updateCaller() {
callerViaGet = updateCaller.caller;
- callerViaGetOwnProperty = Object.getOwnPropertyDescriptor(updateCaller, "caller").value;
+ callerViaGetOwnProperty = functionPrototypeCallerGetter.call(updateCaller);
}
noInline(updateCaller);
Modified: trunk/JSTests/stress/has-own-property-arguments.js (280288 => 280289)
--- trunk/JSTests/stress/has-own-property-arguments.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/has-own-property-arguments.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -5,4 +5,4 @@
class A extends Function {}
shouldBe(new A("'use strict';").hasOwnProperty('arguments'), false);
-shouldBe(new A().hasOwnProperty('arguments'), true);
+shouldBe(new A().hasOwnProperty('arguments'), false);
Modified: trunk/JSTests/stress/object-assign-fast-path.js (280288 => 280289)
--- trunk/JSTests/stress/object-assign-fast-path.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/object-assign-fast-path.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -40,7 +40,7 @@
ok: 42
});
- shouldBe(JSON.stringify(Object.getOwnPropertyNames(result).sort()), `["arguments","caller","length","name","ok","prototype"]`);
+ shouldBe(JSON.stringify(Object.getOwnPropertyNames(result).sort()), `["length","name","ok","prototype"]`);
checkProperty(result, "ok", 42);
}
{
Modified: trunk/JSTests/stress/put-to-proto-chain-overrides-put.js (280288 => 280289)
--- trunk/JSTests/stress/put-to-proto-chain-overrides-put.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/put-to-proto-chain-overrides-put.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -60,9 +60,6 @@
false,
);
-testSetResult(() => function() {}, "arguments", false);
-testSetResult(() => function() {}, "caller", false);
-
// === harness ===
function testSetResult(getTarget, key, expectedResult) {
Modified: trunk/JSTests/stress/reflect-set.js (280288 => 280289)
--- trunk/JSTests/stress/reflect-set.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/stress/reflect-set.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -1204,11 +1204,11 @@
(function functionCase() {
var func = function () { };
shouldBe(Reflect.get(func, 'arguments'), null);
- shouldBe(Reflect.set(func, 'arguments', 42), false);
+ shouldBe(Reflect.set(func, 'arguments', 42), true);
shouldBe(Reflect.get(func, 'arguments'), null);
shouldBe(Reflect.get(func, 'caller'), null);
- shouldBe(Reflect.set(func, 'caller', 42), false);
+ shouldBe(Reflect.set(func, 'caller', 42), true);
shouldBe(Reflect.get(func, 'caller'), null);
receiverTest(function () {}, function () {});
@@ -1219,11 +1219,16 @@
receiverTestIndexed(function () {}, {});
var receiver = {};
- shouldBe(Reflect.set(func, 'arguments', 'V', receiver), false);
+ shouldThrow(() => {
+ Reflect.set(func, 'arguments', 'V', receiver);
+ }, `TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context.`);
shouldBe(Reflect.get(receiver, 'arguments'), undefined);
shouldBe(receiver.hasOwnProperty('arguments'), false);
shouldBe(Reflect.get(func, 'arguments'), null);
- shouldBe(Reflect.set(func, 'caller', 'V', receiver), false);
+
+ shouldThrow(() => {
+ Reflect.set(func, 'caller', 'V', receiver);
+ }, `TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context.`);
shouldBe(Reflect.get(receiver, 'caller'), undefined);
shouldBe(receiver.hasOwnProperty('caller'), false);
shouldBe(Reflect.get(func, 'caller'), null);
Modified: trunk/JSTests/test262/config.yaml (280288 => 280289)
--- trunk/JSTests/test262/config.yaml 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/test262/config.yaml 2021-07-25 22:32:20 UTC (rev 280289)
@@ -32,6 +32,11 @@
- json-modules
paths:
files:
+ # https://github.com/claudepache/es-legacy-function-reflection
+ - test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
+ - test/built-ins/Function/prototype/restricted-property-arguments.js
+ - test/built-ins/Function/prototype/restricted-property-caller.js
+
# Slightly different formatting. We should update test262 side.
- test/intl402/DateTimeFormat/prototype/formatRangeToParts/en-US.js
- test/intl402/DateTimeFormat/prototype/formatRangeToParts/fractionalSecondDigits.js
Modified: trunk/JSTests/test262/expectations.yaml (280288 => 280289)
--- trunk/JSTests/test262/expectations.yaml 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/JSTests/test262/expectations.yaml 2021-07-25 22:32:20 UTC (rev 280289)
@@ -762,10 +762,6 @@
test/built-ins/Object/entries/order-after-define-property.js:
default: 'Test262Error: Expected [a, name] and [name, a] to have the same contents. '
strict mode: 'Test262Error: Expected [a, name] and [name, a] to have the same contents. '
-test/built-ins/Object/internals/DefineOwnProperty/consistent-value-function-arguments.js:
- default: 'Test262Error: Expected SameValue(«null», «[object Arguments]») to be true'
-test/built-ins/Object/internals/DefineOwnProperty/consistent-value-function-caller.js:
- default: 'Test262Error: Expected SameValue(«null», «function g() {'
test/built-ins/Object/internals/DefineOwnProperty/consistent-value-regexp-dollar1.js:
default: 'Test262Error: Expected SameValue(«», «x») to be true'
strict mode: 'Test262Error: Expected SameValue(«», «x») to be true'
Modified: trunk/LayoutTests/ChangeLog (280288 => 280289)
--- trunk/LayoutTests/ChangeLog 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/ChangeLog 2021-07-25 22:32:20 UTC (rev 280289)
@@ -1,3 +1,23 @@
+2021-07-25 Alexey Shvayka <[email protected]>
+
+ Partly implement Function.prototype.{caller,arguments} reflection proposal
+ https://bugs.webkit.org/show_bug.cgi?id=158116
+
+ Reviewed by Yusuke Suzuki.
+
+ * inspector/model/remote-object-get-properties-expected.txt:
+ * inspector/runtime/getDisplayableProperties-expected.txt:
+ * inspector/runtime/getProperties-expected.txt:
+ * js/Object-getOwnPropertyNames-expected.txt:
+ * js/basic-strict-mode-expected.txt:
+ * js/kde/function_arguments-expected.txt:
+ * js/kde/script-tests/function_arguments.js:
+ * js/non-strict-function-properties-expected.txt:
+ * js/script-tests/Object-getOwnPropertyNames.js:
+ * js/script-tests/basic-strict-mode.js:
+ * js/script-tests/non-strict-function-properties.js:
+ * js/script-tests/throw-type-error-is-unique.js:
+
2021-07-25 Wenson Hsieh <[email protected]>
[iOS] Unified field is unselected after focusing URL bar if text was selected in a fixed position container
Modified: trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt (280288 => 280289)
--- trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -365,31 +365,29 @@
description: function () { console.log(arguments); }
OWN PROPERTIES:
- arguments
- caller
+ prototype
length
name
- prototype
__proto__
DISPLAYABLE PROPERTIES:
+ prototype
+ length
+ name
arguments
caller
- length
- name
- prototype
__proto__
ALL PROPERTIES:
- arguments
- caller
+ prototype
length
name
- prototype
toString
apply
call
bind
+ arguments
+ caller
constructor
Symbol(Symbol.hasInstance)
toLocaleString
@@ -422,8 +420,8 @@
DISPLAYABLE PROPERTIES:
length
name
+ arguments
caller
- arguments
__proto__
targetFunction
boundThis
@@ -436,8 +434,8 @@
apply
call
bind
+ arguments
caller
- arguments
constructor
Symbol(Symbol.hasInstance)
toLocaleString
Modified: trunk/LayoutTests/inspector/runtime/getDisplayableProperties-expected.txt (280288 => 280289)
--- trunk/LayoutTests/inspector/runtime/getDisplayableProperties-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/inspector/runtime/getDisplayableProperties-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -25,8 +25,8 @@
"length" => 0 (number) [configurable | isOwn]
"prototype" => "Test" (object) [isOwn]
"name" => "Test" (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
-- Running test case: Runtime.getDisplayableProperties.BoundConstructor
@@ -35,8 +35,8 @@
Properties:
"length" => 0 (number) [configurable | isOwn]
"name" => "bound Test" (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "class Test { }" (function class) []
@@ -48,8 +48,8 @@
Properties:
"length" => 0 (number) [configurable | isOwn]
"name" => "bound Test" (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "class Test { }" (function class) []
@@ -60,11 +60,11 @@
Evaluating _expression_...
Getting displayable properties...
Properties:
- "arguments" => null (object null) [isOwn]
- "caller" => null (object null) [isOwn]
"length" => 3 (number) [configurable | isOwn]
"name" => "" (string) [configurable | isOwn]
"prototype" => "Object" (object) [writable | isOwn]
+ "arguments" => null (object null) [configurable | nativeGetter]
+ "caller" => null (object null) [configurable | nativeGetter]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
-- Running test case: Runtime.getDisplayableProperties.FunctionNoParameters
@@ -71,11 +71,11 @@
Evaluating _expression_...
Getting displayable properties...
Properties:
- "arguments" => null (object null) [isOwn]
- "caller" => null (object null) [isOwn]
"length" => 0 (number) [configurable | isOwn]
"name" => "" (string) [configurable | isOwn]
"prototype" => "Object" (object) [writable | isOwn]
+ "arguments" => null (object null) [configurable | nativeGetter]
+ "caller" => null (object null) [configurable | nativeGetter]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
-- Running test case: Runtime.getDisplayableProperties.BoundFunction
@@ -84,8 +84,8 @@
Properties:
"length" => 3 (number) [configurable | isOwn]
"name" => "bound " (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "function (a, b, c){}" (function) []
@@ -97,8 +97,8 @@
Properties:
"length" => 0 (number) [configurable | isOwn]
"name" => "bound " (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "function (a, b, c){}" (function) []
@@ -111,8 +111,8 @@
Properties:
"length" => 0 (number) [configurable | isOwn]
"name" => "bound " (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "function (){}" (function) []
@@ -124,8 +124,8 @@
Properties:
"length" => 0 (number) [configurable | isOwn]
"name" => "bound " (string) [configurable | isOwn]
+ "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"caller" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
- "arguments" => "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context." (object error) [wasThrown]
"__proto__" => "function () {\n [native code]\n}" (function) [writable | configurable | isOwn]
Internal Properties:
"targetFunction" => "function (){}" (function) []
Modified: trunk/LayoutTests/inspector/runtime/getProperties-expected.txt (280288 => 280289)
--- trunk/LayoutTests/inspector/runtime/getProperties-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/inspector/runtime/getProperties-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -54,8 +54,6 @@
Evaluating _expression_...
Getting own properties...
Properties:
- "arguments" => null (object null) [isOwn]
- "caller" => null (object null) [isOwn]
"length" => 3 (number) [configurable | isOwn]
"name" => "" (string) [configurable | isOwn]
"prototype" => "Object" (object) [writable | isOwn]
@@ -65,8 +63,6 @@
Evaluating _expression_...
Getting own properties...
Properties:
- "arguments" => null (object null) [isOwn]
- "caller" => null (object null) [isOwn]
"length" => 0 (number) [configurable | isOwn]
"name" => "" (string) [configurable | isOwn]
"prototype" => "Object" (object) [writable | isOwn]
Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (280288 => 280289)
--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -11,8 +11,8 @@
PASS getSortedOwnPropertyNames({__proto__:[1,2,3]}) is []
PASS getSortedOwnPropertyNames(Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })) is ['a']
PASS getSortedOwnPropertyNames(Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })) is ['a']
-PASS getSortedOwnPropertyNames(new Function()) is ['arguments', 'caller', 'length', 'name', 'prototype']
-PASS getSortedOwnPropertyNames((function(){var x=new Function();x.__proto__=[1,2,3];return x;})()) is ['arguments', 'caller', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(new Function()) is ['length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames((function(){var x=new Function();x.__proto__=[1,2,3];return x;})()) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(new String('')) is ['length']
PASS getSortedOwnPropertyNames(new String('a')) is ['0', 'length']
PASS getSortedOwnPropertyNames(new String('abc')) is ['0', '1', '2', 'length']
Modified: trunk/LayoutTests/js/basic-strict-mode-expected.txt (280288 => 280289)
--- trunk/LayoutTests/js/basic-strict-mode-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/basic-strict-mode-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -186,8 +186,8 @@
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'); })() is undefined.
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.__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 (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })() is false
+PASS (function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'arguments'); return descriptor.get === descriptor.set; })() is false
PASS 'use strict'; (function f() { for(var i in this); })(); true; is true
PASS 'use strict'̻ threw exception SyntaxError: Invalid character '\u033b'.
PASS (function(){'use strict'̻}) threw exception SyntaxError: Invalid character '\u033b'.
@@ -213,7 +213,7 @@
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"; }).__proto__, "caller").get) is 'function () {\n [native code]\n}'
+PASS String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get) is 'function caller() {\n [native code]\n}'
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/js/kde/function_arguments-expected.txt (280288 => 280289)
--- trunk/LayoutTests/js/kde/function_arguments-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/kde/function_arguments-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -13,9 +13,8 @@
PASS mf.arguments[0] is expected[expno++]
PASS mf.arguments[0] is expected[expno++]
PASS mf.arguments is expected[expno++]
-PASS ReadOnlyOK is true
-PASS DontDeleteOK is true
-PASS DontEnumOK is true
+PASS f.hasOwnProperty('arguments') is false
+PASS f.hasOwnProperty('caller') is false
PASS arg0 is 1
PASS arg1 is 2
PASS arg2 is 3
Modified: trunk/LayoutTests/js/kde/script-tests/function_arguments.js (280288 => 280289)
--- trunk/LayoutTests/js/kde/script-tests/function_arguments.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/kde/script-tests/function_arguments.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -16,42 +16,12 @@
mf(99);
shouldBe("mf.arguments", "expected[expno++]");
-
-// check internal properties of arguments
-
-// Delete
-
-
-// DontEnum
-var foundArgs = false;
-
-var ReadOnlyOK = false;
-var DontDeleteOK = false;
-var DontEnumOK = false;
+// Check that sloppy mode ES5 function doesn't have own 'arguments' and 'caller' properties
function f(a,b,c) {
-
- // ReadOnly
- var newargs = new Object();
- f.arguments = newargs;
- ReadOnlyOK = (f.arguments != newargs);
-
- // DontDelete
- DontDeleteOK = !delete(f.arguments);
- if (f.arguments == undefined || !f.__proto__.hasOwnProperty("arguments"))
- DontDeleteOK = false;
-
- // DontEnum
- var foundArgs = false;
- for (i in f) {
- if (f == "arguments")
- foundArgs = true;
- }
- DontEnumOK = !foundArgs;
+ shouldBeFalse("f.hasOwnProperty('arguments')");
+ shouldBeFalse("f.hasOwnProperty('caller')");
}
f(1,2,3);
-shouldBeTrue("ReadOnlyOK");
-shouldBeTrue("DontDeleteOK");
-shouldBeTrue("DontEnumOK");
// Check that parameter variables are bound to the corresponding
// elements in the arguments array
Modified: trunk/LayoutTests/js/non-strict-function-properties-expected.txt (280288 => 280289)
--- trunk/LayoutTests/js/non-strict-function-properties-expected.txt 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/non-strict-function-properties-expected.txt 2021-07-25 22:32:20 UTC (rev 280289)
@@ -3,15 +3,15 @@
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 Object.getOwnPropertyNames(function () {}).length is 3
+PASS Object.getOwnPropertyNames(function () {}).includes("caller") is false
+PASS Object.getOwnPropertyNames(function () {}).includes("arguments") is false
+PASS (function(){}).hasOwnProperty("caller") is false
PASS (function(){}).__proto__.hasOwnProperty("caller") is true
-PASS (function(){}).hasOwnProperty("arguments") is true
+PASS (function(){}).hasOwnProperty("arguments") is false
PASS (function(){}).__proto__.hasOwnProperty("arguments") is true
-PASS typeof Object.getOwnPropertyDescriptor(foo, "arguments") is "object"
-PASS typeof Object.getOwnPropertyDescriptor(foo, "caller") is "object"
+PASS typeof Object.getOwnPropertyDescriptor(foo, "arguments") is "undefined"
+PASS typeof Object.getOwnPropertyDescriptor(foo, "caller") is "undefined"
PASS foo.caller is null
PASS foo.arguments is null
PASS foo.caller is null
Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (280288 => 280289)
--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -12,8 +12,8 @@
"Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })": "['a']",
"Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })": "['a']",
// Function objects
- "new Function()": "['arguments', 'caller', 'length', 'name', 'prototype']",
- "(function(){var x=new Function();x.__proto__=[1,2,3];return x;})()": "['arguments', 'caller', 'length', 'name', 'prototype']",
+ "new Function()": "['length', 'name', 'prototype']",
+ "(function(){var x=new Function();x.__proto__=[1,2,3];return x;})()": "['length', 'name', 'prototype']",
// String objects
"new String('')": "['length']",
"new String('a')": "['0', 'length']",
Modified: trunk/LayoutTests/js/script-tests/basic-strict-mode.js (280288 => 280289)
--- trunk/LayoutTests/js/script-tests/basic-strict-mode.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/script-tests/basic-strict-mode.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -187,8 +187,8 @@
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'callee').value; })()");
shouldBeUndefined("(function f(arg){'use strict'; return Object.getOwnPropertyDescriptor(arguments, 'caller'); })()");
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.__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; })()");
+shouldBeFalse("(function f(arg){'use strict'; var descriptor = Object.getOwnPropertyDescriptor(f.__proto__, 'caller'); return descriptor.get === descriptor.set; })()");
+shouldBeFalse("(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");
@@ -215,4 +215,4 @@
shouldBeTrue("(function () {try { throw 1; } catch (e) { aGlobal = true; }})(); aGlobal;");
// Make sure this doesn't crash!
-shouldBe('String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get)', "'function () {\\n [native code]\\n}'");
+shouldBe('String(Object.getOwnPropertyDescriptor((function() { "use strict"; }).__proto__, "caller").get)', "'function caller() {\\n [native code]\\n}'");
Modified: trunk/LayoutTests/js/script-tests/non-strict-function-properties.js (280288 => 280289)
--- trunk/LayoutTests/js/script-tests/non-strict-function-properties.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/script-tests/non-strict-function-properties.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -4,19 +4,19 @@
return 1;
}
-shouldBe('Object.getOwnPropertyNames(function () {}).length','5');
+shouldBe('Object.getOwnPropertyNames(function () {}).length', '3');
-shouldBeTrue('Object.getOwnPropertyNames(function () {}).includes("caller")');
-shouldBeTrue('Object.getOwnPropertyNames(function () {}).includes("arguments")');
+shouldBeFalse('Object.getOwnPropertyNames(function () {}).includes("caller")');
+shouldBeFalse('Object.getOwnPropertyNames(function () {}).includes("arguments")');
-shouldBeTrue('(function(){}).hasOwnProperty("caller")');
+shouldBeFalse('(function(){}).hasOwnProperty("caller")');
shouldBeTrue('(function(){}).__proto__.hasOwnProperty("caller")');
-shouldBeTrue('(function(){}).hasOwnProperty("arguments")');
+shouldBeFalse('(function(){}).hasOwnProperty("arguments")');
shouldBeTrue('(function(){}).__proto__.hasOwnProperty("arguments")');
-shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "arguments")', '"object"');
-shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "caller")', '"object"');
+shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "arguments")', '"undefined"');
+shouldBe('typeof Object.getOwnPropertyDescriptor(foo, "caller")', '"undefined"');
shouldBe('foo.caller', 'null');
shouldBe('foo.arguments', 'null');
Modified: trunk/LayoutTests/js/script-tests/throw-type-error-is-unique.js (280288 => 280289)
--- trunk/LayoutTests/js/script-tests/throw-type-error-is-unique.js 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/LayoutTests/js/script-tests/throw-type-error-is-unique.js 2021-07-25 22:32:20 UTC (rev 280289)
@@ -47,13 +47,8 @@
let baseThrowTypeErrorFunction = Object.getOwnPropertyDescriptor(arguments, "callee").get;
let sources = [
- new ThrowTypeErrorSource("Function.prototype", Function.prototype, ["arguments", "caller"]),
- new ThrowTypeErrorSource("Array.prototype.push (builtin)", arrayProtoPush, ["arguments", "caller"]),
- new ThrowTypeErrorSource("Strict function arguments", strictArguments, ["arguments", "caller"]),
- new ThrowTypeErrorSource("Sloppy function arguments", sloppyArguments, ["arguments", "caller"]),
- new ThrowTypeErrorSource("Strict arguments", strictArguments(), ["callee", "caller"]),
- new ThrowTypeErrorSource("Sloppy arguments", sloppyArguments(), ["callee", "caller"]),
- new ThrowTypeErrorSource("Class constructor", (new A()).constructor, ["arguments", "caller"])
+ new ThrowTypeErrorSource("Strict arguments", strictArguments(), ["callee"]),
+ new ThrowTypeErrorSource("Sloppy arguments", sloppyArguments(), ["callee"]),
];
let errors = 0;
Modified: trunk/Source/_javascript_Core/ChangeLog (280288 => 280289)
--- trunk/Source/_javascript_Core/ChangeLog 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-07-25 22:32:20 UTC (rev 280289)
@@ -1,3 +1,91 @@
+2021-07-25 Alexey Shvayka <[email protected]>
+
+ Partly implement Function.prototype.{caller,arguments} reflection proposal
+ https://bugs.webkit.org/show_bug.cgi?id=158116
+
+ Reviewed by Yusuke Suzuki.
+
+ To ensure web-compatibility, only the safe subset of Function.prototype.{caller,arguments}
+ reflection proposal [1] is implemented, which is currently shipped in SpiderMonkey.
+
+ Complete list of differences from the proposed spec:
+
+ 1. Cross-realm receiver function is allowed instead of throwing a TypeError.
+
+ Throwing is likely safe to ship, but #225997 needs to be fixed first for
+ custom properties to receive correct global object.
+
+ 2. Cross-realm caller function is returned instead of `null`.
+
+ Hiding cross-realm caller may break things: we currently have a test for
+ the opposite behavior.
+
+ 3. Defines "caller" and "arguments" setters that throw for disallowed receivers,
+ instead failing silently in sloppy mode.
+
+ This is actually more restrictive than the spec, which is preferable,
+ and aligns with V8 and SM.
+
+ Most importantly, this patch removes own "caller" and "arguments" properties from
+ sloppy mode ES5 functions. They were non-configurable, making it harder to use
+ their holder as a [[ProxyTarget]]. They were also non-writable, with a constantly
+ changing [[Value]], which violated the invariants of internal methods [2].
+
+ As a result, JSFunction methods are greatly simplified, especially defineOwnProperty()
+ and getOwnSpecialPropertyNames(). The latter is now 2.1x faster according to the
+ provided microbenchmark. Also, removes double "prototype" lookup from [[Get]],
+ which is a 10% progression.
+
+ [1]: https://github.com/claudepache/es-legacy-function-reflection
+ [2]: https://tc39.es/ecma262/#sec-invariants-of-the-essential-internal-methods
+
+ * runtime/ClonedArguments.cpp:
+ (JSC::ClonedArguments::getOwnPropertySlot):
+ (JSC::ClonedArguments::materializeSpecials):
+ * runtime/FunctionExecutable.h:
+ * runtime/FunctionPrototype.cpp:
+ (JSC::FunctionPrototype::addFunctionProperties):
+ (JSC::isAllowedReceiverFunctionForCallerAndArguments):
+ (JSC::RetrieveArgumentsFunctor::RetrieveArgumentsFunctor):
+ (JSC::RetrieveArgumentsFunctor::result const):
+ (JSC::RetrieveArgumentsFunctor::operator() const):
+ (JSC::retrieveArguments):
+ (JSC::JSC_DEFINE_CUSTOM_GETTER):
+ (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
+ (JSC::RetrieveCallerFunctionFunctor::result const):
+ (JSC::RetrieveCallerFunctionFunctor::operator() const):
+ (JSC::retrieveCallerFunction):
+ (JSC::JSC_DEFINE_CUSTOM_SETTER):
+ (JSC::FunctionPrototype::initRestrictedProperties): Deleted.
+ * runtime/FunctionPrototype.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertySlot):
+ (JSC::JSFunction::getOwnSpecialPropertyNames):
+ (JSC::JSFunction::put):
+ (JSC::JSFunction::deleteProperty):
+ (JSC::JSFunction::defineOwnProperty):
+ (JSC::RetrieveArgumentsFunctor::RetrieveArgumentsFunctor): Deleted.
+ (JSC::RetrieveArgumentsFunctor::result const): Deleted.
+ (JSC::RetrieveArgumentsFunctor::operator() const): Deleted.
+ (JSC::retrieveArguments): Deleted.
+ (JSC::JSC_DEFINE_CUSTOM_GETTER): Deleted.
+ (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor): Deleted.
+ (JSC::RetrieveCallerFunctionFunctor::result const): Deleted.
+ (JSC::RetrieveCallerFunctionFunctor::operator() const): Deleted.
+ (JSC::retrieveCallerFunction): Deleted.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ (JSC::JSGlobalObject::visitChildrenImpl):
+ * runtime/JSGlobalObject.h:
+ Remove unused m_throwTypeErrorGetterSetter and make [[ThrowTypeError]] lazily-created.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::JSC_DEFINE_HOST_FUNCTION):
+ * runtime/JSGlobalObjectFunctions.h:
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putDirectCustomGetterSetterWithoutTransition):
+ * runtime/JSObject.h:
+
2021-07-24 Yusuke Suzuki <[email protected]>
[JSC] Change most of enum in Yarr to enum-class
Modified: trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -181,7 +181,7 @@
if (ident == vm.propertyNames->callee) {
if (isStrictMode || executable->usesNonSimpleParameterList()) {
- slot.setGetterSlot(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::Accessor, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter());
+ slot.setGetterSlot(thisObject, PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::Accessor, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeGetterSetter());
return true;
}
slot.setValue(thisObject, 0, thisObject->m_callee.get());
@@ -252,7 +252,7 @@
bool isStrictMode = executable->isInStrictContext();
if (isStrictMode || executable->usesNonSimpleParameterList())
- putDirectAccessor(globalObject, vm.propertyNames->callee, this->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::Accessor);
+ putDirectAccessor(globalObject, vm.propertyNames->callee, this->globalObject(vm)->throwTypeErrorArgumentsCalleeGetterSetter(), PropertyAttribute::DontDelete | PropertyAttribute::DontEnum | PropertyAttribute::Accessor);
else
putDirect(vm, vm.propertyNames->callee, JSValue(m_callee.get()));
Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.h (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.h 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.h 2021-07-25 22:32:20 UTC (rev 280289)
@@ -139,12 +139,6 @@
bool isGenerator() const { return isGeneratorParseMode(parseMode()); }
bool isAsyncGenerator() const { return isAsyncGeneratorParseMode(parseMode()); }
bool isMethod() const { return parseMode() == SourceParseMode::MethodMode; }
- bool hasCallerAndArgumentsProperties() const
- {
- // Per https://tc39.github.io/ecma262/#sec-forbidden-extensions, only sloppy-mode non-builtin functions in old-style (pre-ES6) syntactic forms can contain
- // "caller" and "arguments".
- return !isInStrictContext() && parseMode() == SourceParseMode::NormalFunctionMode && !isClassConstructorFunction();
- }
bool hasPrototypeProperty() const
{
return SourceParseModeSet(
Modified: trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/FunctionPrototype.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -22,8 +22,10 @@
#include "FunctionPrototype.h"
#include "BuiltinNames.h"
+#include "ClonedArguments.h"
#include "FunctionExecutable.h"
#include "IntegrityInlines.h"
+#include "JSBoundFunction.h"
#include "JSCInlines.h"
namespace JSC {
@@ -35,6 +37,10 @@
static JSC_DECLARE_HOST_FUNCTION(functionProtoFuncToString);
static JSC_DECLARE_HOST_FUNCTION(callFunctionPrototype);
+static JSC_DECLARE_CUSTOM_GETTER(argumentsGetter);
+static JSC_DECLARE_CUSTOM_GETTER(callerGetter);
+static JSC_DECLARE_CUSTOM_SETTER(callerAndArgumentsSetter);
+
// https://tc39.es/ecma262/#sec-properties-of-the-function-prototype-object
JSC_DEFINE_HOST_FUNCTION(callFunctionPrototype, (JSGlobalObject*, CallFrame*))
{
@@ -60,16 +66,12 @@
*callFunction = putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->builtinNames().callPublicName(), functionPrototypeCallCodeGenerator(vm), static_cast<unsigned>(PropertyAttribute::DontEnum));
putDirectBuiltinFunctionWithoutTransition(vm, globalObject, vm.propertyNames->bind, functionPrototypeBindCodeGenerator(vm), static_cast<unsigned>(PropertyAttribute::DontEnum));
+ putDirectCustomGetterSetterWithoutTransition(vm, vm.propertyNames->arguments, CustomGetterSetter::create(vm, argumentsGetter, callerAndArgumentsSetter), PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor);
+ putDirectCustomGetterSetterWithoutTransition(vm, vm.propertyNames->caller, CustomGetterSetter::create(vm, callerGetter, callerAndArgumentsSetter), PropertyAttribute::DontEnum | PropertyAttribute::CustomAccessor);
+
*hasInstanceSymbolFunction = JSFunction::create(vm, functionPrototypeSymbolHasInstanceCodeGenerator(vm), globalObject);
putDirectWithoutTransition(vm, vm.propertyNames->hasInstanceSymbol, *hasInstanceSymbolFunction, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
}
-
-void FunctionPrototype::initRestrictedProperties(VM& vm, JSGlobalObject* globalObject)
-{
- GetterSetter* errorGetterSetter = globalObject->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();
- putDirectNonIndexAccessorWithoutTransition(vm, vm.propertyNames->caller, errorGetterSetter, PropertyAttribute::DontEnum | PropertyAttribute::Accessor);
- putDirectNonIndexAccessorWithoutTransition(vm, vm.propertyNames->arguments, errorGetterSetter, PropertyAttribute::DontEnum | PropertyAttribute::Accessor);
-}
JSC_DEFINE_HOST_FUNCTION(functionProtoFuncToString, (JSGlobalObject* globalObject, CallFrame* callFrame))
{
@@ -99,4 +101,161 @@
return throwVMTypeError(globalObject, scope);
}
+// https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#isallowedreceiverfunctionforcallerandargumentsfunc-expectedrealm (except step 3)
+static ALWAYS_INLINE bool isAllowedReceiverFunctionForCallerAndArguments(JSFunction* function)
+{
+ if (function->isHostOrBuiltinFunction())
+ return false;
+
+ FunctionExecutable* executable = function->jsExecutable();
+ return !executable->isInStrictContext() && executable->parseMode() == SourceParseMode::NormalFunctionMode && !executable->isClassConstructorFunction();
+}
+
+class RetrieveArgumentsFunctor {
+public:
+ RetrieveArgumentsFunctor(VM& vm, JSFunction* functionObj)
+ : m_vm(vm)
+ , m_targetCallee(functionObj)
+ , m_result(jsNull())
+ {
+ }
+
+ JSValue result() const { return m_result; }
+
+ StackVisitor::Status operator()(StackVisitor& visitor) const
+ {
+ if (!visitor->callee().isCell())
+ return StackVisitor::Continue;
+
+ JSCell* callee = visitor->callee().asCell();
+ if (callee != m_targetCallee)
+ return StackVisitor::Continue;
+
+ m_result = JSValue(visitor->createArguments(m_vm));
+ return StackVisitor::Done;
+ }
+
+private:
+ VM& m_vm;
+ JSObject* m_targetCallee;
+ mutable JSValue m_result;
+};
+
+static JSValue retrieveArguments(VM& vm, CallFrame* callFrame, JSFunction* functionObj)
+{
+ RetrieveArgumentsFunctor functor(vm, functionObj);
+ if (callFrame)
+ callFrame->iterate(vm, functor);
+ return functor.result();
+}
+
+// https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#get-functionprototypearguments
+JSC_DEFINE_CUSTOM_GETTER(argumentsGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSFunction* thisObj = jsDynamicCast<JSFunction*>(vm, JSValue::decode(thisValue));
+ if (!thisObj || !isAllowedReceiverFunctionForCallerAndArguments(thisObj))
+ return throwVMTypeError(globalObject, scope, RestrictedPropertyAccessError);
+
+ return JSValue::encode(retrieveArguments(vm, vm.topCallFrame, thisObj));
+}
+
+class RetrieveCallerFunctionFunctor {
+public:
+ RetrieveCallerFunctionFunctor(JSFunction* functionObj)
+ : m_targetCallee(functionObj)
+ , m_hasFoundFrame(false)
+ , m_hasSkippedToCallerFrame(false)
+ , m_result(jsNull())
+ {
+ }
+
+ JSValue result() const { return m_result; }
+
+ StackVisitor::Status operator()(StackVisitor& visitor) const
+ {
+ if (!visitor->callee().isCell())
+ return StackVisitor::Continue;
+
+ JSCell* callee = visitor->callee().asCell();
+
+ if (callee && callee->inherits<JSBoundFunction>(callee->vm()))
+ return StackVisitor::Continue;
+
+ if (!m_hasFoundFrame && callee != m_targetCallee)
+ return StackVisitor::Continue;
+
+ m_hasFoundFrame = true;
+ if (!m_hasSkippedToCallerFrame) {
+ m_hasSkippedToCallerFrame = true;
+ return StackVisitor::Continue;
+ }
+
+ if (callee)
+ m_result = callee;
+ return StackVisitor::Done;
+ }
+
+private:
+ JSObject* m_targetCallee;
+ mutable bool m_hasFoundFrame;
+ mutable bool m_hasSkippedToCallerFrame;
+ mutable JSValue m_result;
+};
+
+static JSValue retrieveCallerFunction(VM& vm, CallFrame* callFrame, JSFunction* functionObj)
+{
+ RetrieveCallerFunctionFunctor functor(functionObj);
+ if (callFrame)
+ callFrame->iterate(vm, functor);
+ return functor.result();
+}
+
+// https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#get-functionprototypecaller
+JSC_DEFINE_CUSTOM_GETTER(callerGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSFunction* thisObj = jsDynamicCast<JSFunction*>(vm, JSValue::decode(thisValue));
+ if (!thisObj || !isAllowedReceiverFunctionForCallerAndArguments(thisObj))
+ return throwVMTypeError(globalObject, scope, RestrictedPropertyAccessError);
+
+ JSValue caller = retrieveCallerFunction(vm, vm.topCallFrame, thisObj);
+ if (caller.isNull())
+ return JSValue::encode(jsNull());
+
+ // 11. If caller is not an ECMAScript function object, return null.
+ JSFunction* function = jsDynamicCast<JSFunction*>(vm, caller);
+ if (!function || function->isHostOrBuiltinFunction())
+ return JSValue::encode(jsNull());
+
+ // 12. If caller.[[Strict]] is true, return null.
+ if (function->jsExecutable()->isInStrictContext())
+ return JSValue::encode(jsNull());
+
+ // Prevent bodies (private implementations) of generator / async functions from being exposed.
+ // They expect to be called by @generatorResume() & friends with certain arguments, and crash otherwise.
+ // 14. If caller.[[ECMAScriptCode]] is a GeneratorBody, an AsyncFunctionBody, an AsyncGeneratorBody, or an AsyncConciseBody, return null.
+ SourceParseMode parseMode = function->jsExecutable()->parseMode();
+ if (isGeneratorParseMode(parseMode) || isAsyncFunctionParseMode(parseMode))
+ return JSValue::encode(jsNull());
+
+ return JSValue::encode(caller);
+}
+
+JSC_DEFINE_CUSTOM_SETTER(callerAndArgumentsSetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, EncodedJSValue, PropertyName))
+{
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ JSFunction* thisObj = jsDynamicCast<JSFunction*>(vm, JSValue::decode(thisValue));
+ if (!thisObj || !isAllowedReceiverFunctionForCallerAndArguments(thisObj))
+ throwTypeError(globalObject, scope, RestrictedPropertyAccessError);
+
+ return true;
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/FunctionPrototype.h (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/FunctionPrototype.h 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/FunctionPrototype.h 2021-07-25 22:32:20 UTC (rev 280289)
@@ -37,8 +37,6 @@
void addFunctionProperties(VM&, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction, JSFunction** hasInstanceSymbolFunction);
- void initRestrictedProperties(VM&, JSGlobalObject*);
-
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
{
return Structure::create(vm, globalObject, proto, TypeInfo(InternalFunctionType, StructureFlags), info());
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -29,7 +29,6 @@
#include "AsyncGeneratorPrototype.h"
#include "BuiltinNames.h"
#include "CatchScope.h"
-#include "ClonedArguments.h"
#include "CommonIdentifiers.h"
#include "CallFrame.h"
#include "GeneratorPrototype.h"
@@ -53,9 +52,6 @@
return throwVMError(globalObject, scope, createNotAConstructorError(globalObject, callFrame->jsCallee()));
}
-static JSC_DECLARE_CUSTOM_GETTER(argumentsGetter);
-static JSC_DECLARE_CUSTOM_GETTER(callerGetter);
-
const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFunction) };
const ClassInfo JSStrictFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSStrictFunction) };
const ClassInfo JSSloppyFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSSloppyFunction) };
@@ -300,139 +296,6 @@
return callData;
}
-class RetrieveArgumentsFunctor {
-public:
- RetrieveArgumentsFunctor(VM& vm, JSFunction* functionObj)
- : m_vm(vm)
- , m_targetCallee(functionObj)
- , m_result(jsNull())
- {
- }
-
- JSValue result() const { return m_result; }
-
- StackVisitor::Status operator()(StackVisitor& visitor) const
- {
- if (!visitor->callee().isCell())
- return StackVisitor::Continue;
-
- JSCell* callee = visitor->callee().asCell();
- if (callee != m_targetCallee)
- return StackVisitor::Continue;
-
- m_result = JSValue(visitor->createArguments(m_vm));
- return StackVisitor::Done;
- }
-
-private:
- VM& m_vm;
- JSObject* m_targetCallee;
- mutable JSValue m_result;
-};
-
-static JSValue retrieveArguments(VM& vm, CallFrame* callFrame, JSFunction* functionObj)
-{
- RetrieveArgumentsFunctor functor(vm, functionObj);
- if (callFrame)
- callFrame->iterate(vm, functor);
- return functor.result();
-}
-
-JSC_DEFINE_CUSTOM_GETTER(argumentsGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
-{
- VM& vm = globalObject->vm();
- JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
- ASSERT(!thisObj->isHostFunction());
-
- return JSValue::encode(retrieveArguments(vm, vm.topCallFrame, thisObj));
-}
-
-class RetrieveCallerFunctionFunctor {
-public:
- RetrieveCallerFunctionFunctor(JSFunction* functionObj)
- : m_targetCallee(functionObj)
- , m_hasFoundFrame(false)
- , m_hasSkippedToCallerFrame(false)
- , m_result(jsNull())
- {
- }
-
- JSValue result() const { return m_result; }
-
- StackVisitor::Status operator()(StackVisitor& visitor) const
- {
- if (!visitor->callee().isCell())
- return StackVisitor::Continue;
-
- JSCell* callee = visitor->callee().asCell();
-
- if (callee && callee->inherits<JSBoundFunction>(callee->vm()))
- return StackVisitor::Continue;
-
- if (!m_hasFoundFrame && (callee != m_targetCallee))
- return StackVisitor::Continue;
-
- m_hasFoundFrame = true;
- if (!m_hasSkippedToCallerFrame) {
- m_hasSkippedToCallerFrame = true;
- return StackVisitor::Continue;
- }
-
- if (callee)
- m_result = callee;
- return StackVisitor::Done;
- }
-
-private:
- JSObject* m_targetCallee;
- mutable bool m_hasFoundFrame;
- mutable bool m_hasSkippedToCallerFrame;
- mutable JSValue m_result;
-};
-
-static JSValue retrieveCallerFunction(VM& vm, CallFrame* callFrame, JSFunction* functionObj)
-{
- RetrieveCallerFunctionFunctor functor(functionObj);
- if (callFrame)
- callFrame->iterate(vm, functor);
- return functor.result();
-}
-
-JSC_DEFINE_CUSTOM_GETTER(callerGetter, (JSGlobalObject* globalObject, EncodedJSValue thisValue, PropertyName))
-{
- VM& vm = globalObject->vm();
-
- JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
- ASSERT(!thisObj->isHostFunction());
- JSValue caller = retrieveCallerFunction(vm, vm.topCallFrame, thisObj);
-
- // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller.
- if (!caller.isObject() || !asObject(caller)->inherits<JSFunction>(vm)) {
- // It isn't a JSFunction, but if it is a JSCallee from a program or eval call or an internal constructor, return null.
- if (jsDynamicCast<JSCallee*>(vm, caller) || jsDynamicCast<InternalFunction*>(vm, caller))
- return JSValue::encode(jsNull());
- return JSValue::encode(caller);
- }
- JSFunction* function = jsCast<JSFunction*>(caller);
-
- // Firefox returns null for native code callers, so we match that behavior.
- if (function->isHostOrBuiltinFunction())
- return JSValue::encode(jsNull());
-
- if (function->jsExecutable()->isInStrictContext())
- return JSValue::encode(jsNull());
-
- // Prevent bodies (private implementations) of generator / async functions from being exposed.
- // They are called by @generatorResume() & friends, expecting certain arguments, and crash otherwise.
- // Also, hide generator / async function wrappers for consistency and because it's on standards track:
- // https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md#get-functionprototypecaller (step 14)
- SourceParseMode parseMode = function->jsExecutable()->parseMode();
- if (isGeneratorParseMode(parseMode) || isAsyncFunctionParseMode(parseMode))
- return JSValue::encode(jsNull());
-
- return JSValue::encode(caller);
-}
-
bool JSFunction::getOwnPropertySlot(JSObject* object, JSGlobalObject* globalObject, PropertyName propertyName, PropertySlot& slot)
{
VM& vm = globalObject->vm();
@@ -475,21 +338,7 @@
ASSERT(isValidOffset(offset));
}
slot.setValue(thisObject, attributes, thisObject->getDirect(offset), offset);
- }
-
- if (propertyName == vm.propertyNames->arguments) {
- if (!thisObject->jsExecutable()->hasCallerAndArgumentsProperties())
- RELEASE_AND_RETURN(scope, Base::getOwnPropertySlot(thisObject, globalObject, propertyName, slot));
-
- slot.setCacheableCustom(thisObject, PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete, argumentsGetter);
return true;
-
- } else if (propertyName == vm.propertyNames->caller) {
- if (!thisObject->jsExecutable()->hasCallerAndArgumentsProperties())
- RELEASE_AND_RETURN(scope, Base::getOwnPropertySlot(thisObject, globalObject, propertyName, slot));
-
- slot.setCacheableCustom(thisObject, PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum | PropertyAttribute::DontDelete, callerGetter);
- return true;
}
thisObject->reifyLazyPropertyIfNeeded(vm, globalObject, propertyName);
@@ -502,31 +351,14 @@
{
JSFunction* thisObject = jsCast<JSFunction*>(object);
VM& vm = globalObject->vm();
- auto scope = DECLARE_THROW_SCOPE(vm);
if (mode == DontEnumPropertiesMode::Include) {
- if (!thisObject->isHostOrBuiltinFunction()) {
- // Make sure prototype has been reified.
- PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry, &vm);
- thisObject->methodTable(vm)->getOwnPropertySlot(thisObject, globalObject, vm.propertyNames->prototype, slot);
- RETURN_IF_EXCEPTION(scope, void());
-
- if (thisObject->jsExecutable()->hasCallerAndArgumentsProperties()) {
- propertyNames.add(vm.propertyNames->arguments);
- propertyNames.add(vm.propertyNames->caller);
- }
- if (!thisObject->hasReifiedLength())
- propertyNames.add(vm.propertyNames->length);
- if (!thisObject->hasReifiedName())
- propertyNames.add(vm.propertyNames->name);
- } else {
- if (thisObject->isBuiltinFunction() || thisObject->inherits<JSBoundFunction>(vm)) {
- if (!thisObject->hasReifiedLength())
- propertyNames.add(vm.propertyNames->length);
- if (!thisObject->hasReifiedName())
- propertyNames.add(vm.propertyNames->name);
- }
- }
+ if (!thisObject->hasReifiedLength())
+ propertyNames.add(vm.propertyNames->length);
+ if (!thisObject->hasReifiedName())
+ propertyNames.add(vm.propertyNames->name);
+ if (!thisObject->isHostOrBuiltinFunction() && thisObject->jsExecutable()->hasPrototypeProperty())
+ propertyNames.add(vm.propertyNames->prototype);
}
}
@@ -566,13 +398,6 @@
RELEASE_AND_RETURN(scope, Base::put(thisObject, globalObject, propertyName, value, slot));
}
- if (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller) {
- if (!thisObject->jsExecutable()->hasCallerAndArgumentsProperties())
- RELEASE_AND_RETURN(scope, Base::put(thisObject, globalObject, propertyName, value, slot));
-
- slot.disableCaching();
- return typeError(globalObject, scope, slot.isStrictMode(), ReadonlyPropertyWriteError);
- }
PropertyStatus propertyType = thisObject->reifyLazyPropertyIfNeeded(vm, globalObject, propertyName);
if (isLazy(propertyType))
slot.disableCaching();
@@ -598,14 +423,9 @@
RETURN_IF_EXCEPTION(scope, false);
} else if (vm.deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable) {
// For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
- FunctionExecutable* executable = thisObject->jsExecutable();
-
- if ((propertyName == vm.propertyNames->caller || propertyName == vm.propertyNames->arguments) && executable->hasCallerAndArgumentsProperties())
+ if (propertyName == vm.propertyNames->prototype && thisObject->jsExecutable()->hasPrototypeProperty())
return false;
- if (propertyName == vm.propertyNames->prototype && executable->hasPrototypeProperty())
- return false;
-
thisObject->reifyLazyPropertyIfNeeded(vm, globalObject, propertyName);
RETURN_IF_EXCEPTION(scope, false);
}
@@ -643,45 +463,12 @@
if (FunctionRareData* rareData = thisObject->rareData())
rareData->clear("Store to prototype property of a function");
slot.disallowVMEntry.reset();
- RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, propertyName, descriptor, throwException));
- }
-
- bool valueCheck;
- if (propertyName == vm.propertyNames->arguments) {
- if (!thisObject->jsExecutable()->hasCallerAndArgumentsProperties())
- RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, propertyName, descriptor, throwException));
-
- valueCheck = !descriptor.value();
- if (!valueCheck) {
- valueCheck = sameValue(globalObject, descriptor.value(), retrieveArguments(vm, vm.topCallFrame, thisObject));
- RETURN_IF_EXCEPTION(scope, false);
- }
- } else if (propertyName == vm.propertyNames->caller) {
- if (!thisObject->jsExecutable()->hasCallerAndArgumentsProperties())
- RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, propertyName, descriptor, throwException));
-
- valueCheck = !descriptor.value();
- if (!valueCheck) {
- valueCheck = sameValue(globalObject, descriptor.value(), retrieveCallerFunction(vm, vm.topCallFrame, thisObject));
- RETURN_IF_EXCEPTION(scope, false);
- }
} else {
thisObject->reifyLazyPropertyIfNeeded(vm, globalObject, propertyName);
RETURN_IF_EXCEPTION(scope, false);
- RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, propertyName, descriptor, throwException));
}
-
- if (descriptor.configurablePresent() && descriptor.configurable())
- return typeError(globalObject, scope, throwException, UnconfigurablePropertyChangeConfigurabilityError);
- if (descriptor.enumerablePresent() && descriptor.enumerable())
- return typeError(globalObject, scope, throwException, UnconfigurablePropertyChangeEnumerabilityError);
- if (descriptor.isAccessorDescriptor())
- return typeError(globalObject, scope, throwException, UnconfigurablePropertyChangeAccessMechanismError);
- if (descriptor.writablePresent() && descriptor.writable())
- return typeError(globalObject, scope, throwException, UnconfigurablePropertyChangeWritabilityError);
- if (!valueCheck)
- return typeError(globalObject, scope, throwException, ReadonlyPropertyChangeError);
- return true;
+
+ RELEASE_AND_RETURN(scope, Base::defineOwnProperty(object, globalObject, propertyName, descriptor, throwException));
}
// ECMA 13.2.2 [[Construct]]
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -781,12 +781,6 @@
});
m_functionProtoHasInstanceSymbolFunction.set(vm, this, hasInstanceSymbolFunction);
- m_throwTypeErrorGetterSetter.initLater(
- [] (const Initializer<GetterSetter>& init) {
- JSFunction* thrower = init.owner->throwTypeErrorFunction();
- GetterSetter* getterSetter = GetterSetter::create(init.vm, init.owner, thrower, thrower);
- init.set(getterSetter);
- });
m_nullGetterFunction.set(vm, this, NullGetterFunction::create(vm, NullGetterFunction::createStructure(vm, this, m_functionPrototype.get())));
Structure* nullSetterFunctionStructure = NullSetterFunction::createStructure(vm, this, m_functionPrototype.get());
@@ -802,16 +796,15 @@
m_functionPrototype->structure(vm)->setPrototypeWithoutTransition(vm, m_objectPrototype.get());
m_objectStructureForObjectConstructor.set(vm, this, vm.structureCache.emptyObjectStructureForPrototype(this, m_objectPrototype.get(), JSFinalObject::defaultInlineCapacity()));
m_objectProtoValueOfFunction.set(vm, this, jsCast<JSFunction*>(objectPrototype()->getDirect(vm, vm.propertyNames->valueOf)));
-
- JSFunction* thrower = JSFunction::create(vm, this, 0, emptyString(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);
- thrower->freeze(vm);
- GetterSetter* getterSetter = GetterSetter::create(vm, this, thrower, thrower);
- m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.set(vm, this, getterSetter);
-
- m_functionPrototype->initRestrictedProperties(vm, this);
m_speciesGetterSetter.set(vm, this, GetterSetter::create(vm, this, JSFunction::create(vm, globalOperationsSpeciesGetterCodeGenerator(vm), this), nullptr));
+ m_throwTypeErrorArgumentsCalleeGetterSetter.initLater(
+ [] (const Initializer<GetterSetter>& init) {
+ JSFunction* thrower = JSFunction::create(init.vm, init.owner, 0, emptyString(), globalFuncThrowTypeErrorArgumentsCalleeAndCaller);
+ thrower->freeze(init.vm);
+ init.set(GetterSetter::create(init.vm, init.owner, thrower, thrower));
+ });
m_typedArrayProto.initLater(
[] (const Initializer<JSTypedArrayViewPrototype>& init) {
init.set(JSTypedArrayViewPrototype::create(init.vm, init.owner, JSTypedArrayViewPrototype::createStructure(init.vm, init.owner, init.owner->m_objectPrototype.get())));
@@ -2108,9 +2101,8 @@
visitor.append(thisObject->m_objectProtoValueOfFunction);
thisObject->m_numberProtoToStringFunction.visit(visitor);
visitor.append(thisObject->m_functionProtoHasInstanceSymbolFunction);
- thisObject->m_throwTypeErrorGetterSetter.visit(visitor);
visitor.append(thisObject->m_regExpProtoSymbolReplace);
- visitor.append(thisObject->m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter);
+ thisObject->m_throwTypeErrorArgumentsCalleeGetterSetter.visit(visitor);
thisObject->m_moduleLoader.visit(visitor);
visitor.append(thisObject->m_objectPrototype);
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2021-07-25 22:32:20 UTC (rev 280289)
@@ -340,9 +340,8 @@
LazyProperty<JSGlobalObject, JSFunction> m_numberProtoToStringFunction;
WriteBarrier<JSFunction> m_objectProtoValueOfFunction;
WriteBarrier<JSFunction> m_functionProtoHasInstanceSymbolFunction;
- LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorGetterSetter;
WriteBarrier<JSObject> m_regExpProtoSymbolReplace;
- WriteBarrier<GetterSetter> m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter;
+ LazyProperty<JSGlobalObject, GetterSetter> m_throwTypeErrorArgumentsCalleeGetterSetter;
LazyProperty<JSGlobalObject, JSModuleLoader> m_moduleLoader;
@@ -696,10 +695,7 @@
JSObject* regExpProtoSymbolReplaceFunction() const { return m_regExpProtoSymbolReplace.get(); }
GetterSetter* regExpProtoGlobalGetter() const;
GetterSetter* regExpProtoUnicodeGetter() const;
- GetterSetter* throwTypeErrorArgumentsCalleeAndCallerGetterSetter()
- {
- return m_throwTypeErrorArgumentsCalleeAndCallerGetterSetter.get();
- }
+ GetterSetter* throwTypeErrorArgumentsCalleeGetterSetter() const { return m_throwTypeErrorArgumentsCalleeGetterSetter.get(this); }
JSModuleLoader* moduleLoader() const { return m_moduleLoader.get(this); }
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -49,6 +49,7 @@
namespace JSC {
const ASCIILiteral ObjectProtoCalledOnNullOrUndefinedError { "Object.prototype.__proto__ called on null or undefined"_s };
+const ASCIILiteral RestrictedPropertyAccessError { "'arguments', 'callee', and 'caller' cannot be accessed in this context."_s };
template<unsigned charactersCount>
static Bitmap<256> makeCharacterBitmap(const char (&characters)[charactersCount])
@@ -693,7 +694,7 @@
{
VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- return throwVMTypeError(globalObject, scope, "'arguments', 'callee', and 'caller' cannot be accessed in this context.");
+ return throwVMTypeError(globalObject, scope, RestrictedPropertyAccessError);
}
JSC_DEFINE_HOST_FUNCTION(globalFuncMakeTypeError, (JSGlobalObject* globalObject, CallFrame* callFrame))
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.h 2021-07-25 22:32:20 UTC (rev 280289)
@@ -36,6 +36,7 @@
// is a 0.5% reduction.
extern const ASCIILiteral ObjectProtoCalledOnNullOrUndefinedError;
+extern const ASCIILiteral RestrictedPropertyAccessError;
JSC_DECLARE_HOST_FUNCTION(globalFuncEval);
JSC_DECLARE_HOST_FUNCTION(globalFuncParseInt);
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2021-07-25 22:32:20 UTC (rev 280289)
@@ -2000,6 +2000,22 @@
return result;
}
+void JSObject::putDirectCustomGetterSetterWithoutTransition(VM& vm, PropertyName propertyName, JSValue value, unsigned attributes)
+{
+ ASSERT(!parseIndex(propertyName));
+ ASSERT(value.isCustomGetterSetter());
+ ASSERT(attributes & PropertyAttribute::CustomAccessorOrValue);
+
+ StructureID structureID = this->structureID();
+ Structure* structure = vm.heap.structureIDTable().get(structureID);
+ PropertyOffset offset = prepareToPutDirectWithoutTransition(vm, propertyName, attributes, structureID, structure);
+ putDirect(vm, offset, value);
+
+ if (attributes & PropertyAttribute::ReadOnly)
+ structure->setContainsReadOnlyProperties();
+ structure->setHasCustomGetterSetterPropertiesWithProtoCheck(propertyName == vm.propertyNames->underscoreProto);
+}
+
bool JSObject::putDirectNonIndexAccessor(VM& vm, PropertyName propertyName, GetterSetter* accessor, unsigned attributes)
{
ASSERT(attributes & PropertyAttribute::Accessor);
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (280288 => 280289)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2021-07-25 19:40:36 UTC (rev 280288)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2021-07-25 22:32:20 UTC (rev 280289)
@@ -652,6 +652,7 @@
void putDirectNonIndexAccessorWithoutTransition(VM&, PropertyName, GetterSetter*, unsigned attributes);
bool putDirectAccessor(JSGlobalObject*, PropertyName, GetterSetter*, unsigned attributes);
JS_EXPORT_PRIVATE bool putDirectCustomAccessor(VM&, PropertyName, JSValue, unsigned attributes);
+ void putDirectCustomGetterSetterWithoutTransition(VM&, PropertyName, JSValue, unsigned attributes);
bool putGetter(JSGlobalObject*, PropertyName, JSValue, unsigned attributes);
bool putSetter(JSGlobalObject*, PropertyName, JSValue, unsigned attributes);