Bug 239797 - %ThrowTypeError% is defined more than once per realm
Summary: %ThrowTypeError% is defined more than once per realm
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-04-26 18:12 PDT by Richard Gibson
Modified: 2022-06-09 18:15 PDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Gibson 2022-04-26 18:12:27 PDT
This is a JavaScriptCore analog of SpiderMonkey https://bugzilla.mozilla.org/show_bug.cgi?id=1484547

https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-addrestrictedfunctionproperties and https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-createunmappedargumentsobject specify that the getter and setter for each of `Function.prototype` "caller", `Function.prototype` "arguments", and strict-mode function body `arguments` "callee" should all be the same %ThrowTypeError% built-in function. However, JavaScriptCore returns a distinct value for all but the getter/setter pair for strict-mode `arguments` "callee":

```js
(function(){
  "use strict";
  const inputs = [
    ["Function.prototype `caller` getter", Object.getOwnPropertyDescriptor(Function.prototype, "caller").get],
    ["Function.prototype `caller` setter", Object.getOwnPropertyDescriptor(Function.prototype, "caller").set],
    ["Function.prototype `arguments` getter", Object.getOwnPropertyDescriptor(Function.prototype, "arguments").get],
    ["Function.prototype `arguments` setter", Object.getOwnPropertyDescriptor(Function.prototype, "arguments").set],
    ["arguments `callee` getter", Object.getOwnPropertyDescriptor(arguments, "callee").get],
    ["arguments `callee` setter", Object.getOwnPropertyDescriptor(arguments, "callee").set],
  ];
  const groups = new Map();
  for (let [label, fn] of new Map(inputs)) {
    const group = groups.get(fn) || groups.set(fn, []).get(fn);
    group.push(label);
  }
  return JSON.stringify([...groups.values()], null, 2);
})()
/* =>
[
  [
    "Function.prototype `caller` getter"
  ],
  [
    "Function.prototype `caller` setter"
  ],
  [
    "Function.prototype `arguments` getter"
  ],
  [
    "Function.prototype `arguments` setter"
  ],
  [
    "arguments `callee` getter",
    "arguments `callee` setter"
  ]
]
*/
```
Comment 1 Yusuke Suzuki 2022-04-28 16:24:25 PDT
Nice catch!
Comment 2 Radar WebKit Bug Importer 2022-05-03 18:13:14 PDT
<rdar://problem/92704818>
Comment 3 Yusuke Suzuki 2022-06-03 07:17:01 PDT
"arguments `callee` getter" and "arguments `callee` setter" should have the same %ThrowTypeError%, but for the other cases, we are currently following to https://github.com/claudepache/es-legacy-function-reflection/blob/master/spec.md
Comment 4 Richard Gibson 2022-06-03 09:06:17 PDT
Are you saying that you conform with a Stage 1 proposal rather than the published specification? If so, why?
Comment 5 Alexey Shvayka 2022-06-09 18:15:38 PDT
(In reply to Richard Gibson from comment #4)
> Are you saying that you conform with a Stage 1 proposal rather than the
> published specification? If so, why?

Yes, we implement the Stage 1 proposal almost in full (except for cross-realm leakage which we still allow).

I've determined two benefits in aligning with SM and moving accessors to Function.prototype:
  * that greatly simplified our JSFunction overrides;
  * a userland function with own non-configurable properties was problematic to use as [[ProxyTarget]].