{"action":"created","issue":{"url":"https://api.github.com/repos/tc39/proposal-decorators/issues/180","repository_url":"https://api.github.com/repos/tc39/proposal-decorators","labels_url":"https://api.github.com/repos/tc39/proposal-decorators/issues/180/labels{/name}","comments_url":"https://api.github.com/repos/tc39/proposal-decorators/issues/180/comments","events_url":"https://api.github.com/repos/tc39/proposal-decorators/issues/180/events","html_url":"https://github.com/tc39/proposal-decorators/issues/180","id":386787026,"node_id":"MDU6SXNzdWUzODY3ODcwMjY=","number":180,"title":"Restrict the interaction of decorators and private names to ensure limited overhead","user":{"login":"littledan","id":189835,"node_id":"MDQ6VXNlcjE4OTgzNQ==","avatar_url":"https://avatars3.githubusercontent.com/u/189835?v=4","gravatar_id":"","url":"https://api.github.com/users/littledan","html_url":"https://github.com/littledan","followers_url":"https://api.github.com/users/littledan/followers","following_url":"https://api.github.com/users/littledan/following{/other_user}","gists_url":"https://api.github.com/users/littledan/gists{/gist_id}","starred_url":"https://api.github.com/users/littledan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/littledan/subscriptions","organizations_url":"https://api.github.com/users/littledan/orgs","repos_url":"https://api.github.com/users/littledan/repos","events_url":"https://api.github.com/users/littledan/events{/privacy}","received_events_url":"https://api.github.com/users/littledan/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":6,"created_at":"2018-12-03T12:02:46Z","updated_at":"2018-12-13T07:59:25Z","closed_at":null,"author_association":"MEMBER","body":"Private methods and accessors should not take up more space per instance than a word per \"brand\" (class in the class hierarchy), even with the conjunction of decorators and hashtable-mode objects. Various JS engine maintainers (@gsathya, @verwaest, @jorendorff) have pointed out to me that the current design does not really support this sort of guarantee in general. Let's think about how we could make it the case, while maintaining the existing \"brand check\" semantics. At the same time, maybe we could use this as an opportunity to phrase the specification in a way that the brand checking in private methods could be used in other contexts, e.g., WebIDL (@annevk recently suggested to me that WebIDL could use some formalization here).\r\n\r\nSome high-level notes about one approach I've been thinking about--I'd be interested if anyone has other ideas about how to achieve this:\r\n- New private object model: Private methods and accessors are stored on the private name, together with a \"brand\". Objects have a list of brands, alongside their list of private fields.\r\n- Mental model: Private fields are a WeakMap, and private methods/accessors are a WeakSet, which is a consolidated set for all the private methods in that class.\r\n- Logic to read a private name (similar for writing):\r\n    1. Check the private name type, either `~brand~` or `~field~`\r\n    1. If `~field~`, search the [[PrivateFields]] list on the instance and return the result, or throw a TypeError when missing.\r\n    1. If `~brand~`, check the [[Brands]] list on the instance, based on the private name's [[Brand]] internal slot, and throw a TypeError if missing.\r\n    1. If the private name has a [[Value]] (it's a method), return the value\r\n    1. Otherwise, if it has a [[Getter]], call the getter\r\n    1. Otherwise, throw a TypeError\r\n- New private decorator restriction:\r\n    1. Undecorated private class elements get the brand and value/getter/setter fields from the syntax.\r\n    1. A PrivateName can only be used either for a field (reusable as a field) or, if used for a private method/accessor, *cannot be used a second time*--only usable in one class.\r\n    1. No need to include writability/enumerability/configurability on a private field or method (meaningless/redundant), just initializer/value/get/set\r\n    1. Future proposals may include a way to repeat a brand from one class to another, but that's v2 (it can't really be done well in v1 even before this change). You can leak a PrivateName for reading/checking, but only inherit for sharing writing.\r\n- Use in WebIDL of brands:\r\n    - Platform objects have a cross-realm [[Brand]] that the constructor puts on the instance\r\n    - JS-style mixins in WebIDL could be supported similarly, taking advantage of adding a brand later in an object's lifetime e.g., as suggested by @kenchris in https://github.com/littledan/serializable-objects/issues/3\r\n    - TODO(@littledan): Read how various engines implement platform object brand checks, and make sure it's all consistent\r\n\r\nThoughts?"},"comment":{"url":"https://api.github.com/repos/tc39/proposal-decorators/issues/comments/446875675","html_url":"https://github.com/tc39/proposal-decorators/issues/180#issuecomment-446875675","issue_url":"https://api.github.com/repos/tc39/proposal-decorators/issues/180","id":446875675,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0Njg3NTY3NQ==","user":{"login":"nicolo-ribaudo","id":7000710,"node_id":"MDQ6VXNlcjcwMDA3MTA=","avatar_url":"https://avatars3.githubusercontent.com/u/7000710?v=4","gravatar_id":"","url":"https://api.github.com/users/nicolo-ribaudo","html_url":"https://github.com/nicolo-ribaudo","followers_url":"https://api.github.com/users/nicolo-ribaudo/followers","following_url":"https://api.github.com/users/nicolo-ribaudo/following{/other_user}","gists_url":"https://api.github.com/users/nicolo-ribaudo/gists{/gist_id}","starred_url":"https://api.github.com/users/nicolo-ribaudo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nicolo-ribaudo/subscriptions","organizations_url":"https://api.github.com/users/nicolo-ribaudo/orgs","repos_url":"https://api.github.com/users/nicolo-ribaudo/repos","events_url":"https://api.github.com/users/nicolo-ribaudo/events{/privacy}","received_events_url":"https://api.github.com/users/nicolo-ribaudo/received_events","type":"User","site_admin":false},"created_at":"2018-12-13T07:59:25Z","updated_at":"2018-12-13T07:59:25Z","author_association":"CONTRIBUTOR","body":"> Undecorated private class elements get the brand and value/getter/setter fields from the syntax.\r\n\r\nDoes an undecorated field inside a decorated class count as undecorated?"}}
{"actor":{"display_login":"nicolo-ribaudo"}}