-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editorial: Add a few well-known intrinsic objects #1105
Conversation
These will be helpful in solving whatwg/webidl#254.
This list is getting so huge. How much bigger will it get? Do we need to consider another way to handle well-known intrinsics? E.g. you could imagine an abstract operation GetIntrinsic with a parameter path where each path segment corresponds to the name of a property starting on the global? So, e.g., %ArrayProto_keys% becomes GetIntrinsic("Array.prototype.keys"). Then we can reserve %-style for "anonymous" intrinsics like AsyncFunctionPrototype. Thoughts? |
There are two questions there, which I suspect are orthogonal:
|
I believe the spec right now is mostly pretty consistent in having one "statement" on each line in algorithms, and to do that with GetIntrinsic will definitely increase a lot of lines.
I'm fine with not listing all of them, but note that there are some intrinsics that are not In any case I believe this discussion isn't directly related to the PR. I'd be happy to offer opinions outside of this issue but I don't think it should block whatwg/webidl#254. |
Technically, I don't think whatwg/webidl#254 is blocked on this. It isn't constrained to use the %Foo% syntax, it could just use the 'column 3' prose from the patch. (This isn't an objection to the PR.) |
I don't think there is any problem with nesting a calls (it's used in quite a few places I can see, e.g. the nesting of Get inside ToBoolean here).
If there's an active thing the spec has to do to "export" a symbol, an upfront listing makes sense. Right now it's an easy way to figure out all the well-known intrinsics that are DFN's cross the spec. But I don't think it's super useful in-and-of-itself and wouldn't mind deleting most of it if we can find a better convention. |
It's important to remember that this table is actually the basis for some more formal infrastructure, namely the [[Intrinsics]] field. See in particular https://tc39.github.io/ecma262/#sec-createintrinsics. That is, in the rest of the spec, %Foo% is actually shorthand for I'm not sure how to spec something like GetIntrinsic that works on a similar rigorous stashed-ahead-of-time foundation. (Also, please ensure that any solution here allows for looking up the intrinsic in a specific realm, even if it defaults to the current Realm Record. We use the realm.[[Intrinsics]].[[%Foo%]] syntax in Web IDL a few times.) |
Also, please note that the %foo% notation and the supporting definitions were added to clear up realm-related ambiguities that had existed in previous editions that used various prose formulations to refer to built-ins and what we now call "intrinsics". Any changes need to take into account both that there are no actual ambiguity and that the new notation is not likely to be read ambiguously. The nice thing about %foo% is that there are no hints WRT what it might mean so everybody who is serious about understanding the specification has to initially look it up. |
Nobody mentioned it yet, and I'm not entirely sure, but isn't this also useful information for implementations to have these gathered in a single place? Which objects they need to have a safe reference for? |
@annevk I think the set of things that actually needs to be kept around in a real implementation will differ somewhat from what the spec lists (in both directions, including some additional things and leaving out some things). It seems like these particular objects are needed for export just to call the original versions of the algorithms, rather than to actually refer to particular ES-defined objects with identity. ECMA-402 has a number of similar usages of %-identified functions. What if we referred to these algorithms instead by factoring out the algorithm into a separate abstract algorithm to refer to directly? This would avoid the need for a table, and also avoid the need to make reference to ECMAScript semantic concepts like |
That sounds like a good division. If you need to reuse an algorithm, abstract it; if you need the initial version of an object, make it an intrinsic. (I'm wondering again how we want to keep track of downstream dependencies so future editors won't be misled into thinking they can inline some of those abstract operations or remove intrinsics.) |
From that point of view, I think Table 7 is bigger than it needs to be. E.g. consider %ArrayProto_entries% or %isNaN%: I don't think there's anything in the spec that would require an implementation to keep a "safe reference" (assuming I know what you mean by that) to either of them. I'm not sure how many of these there are: they aren't something you can just grep the spec for. Maybe they're there for the benefit of other specs (as in this PR), but it seems like we need a better system, where other specs can get the benefit without requiring additions to Table 7. |
There are a few current uses of intrinsics where an abstract operation wouldn’t suffice; such as |
Not sure I agree. Do you have an example? |
It's a little tricky in that not every intrinsic is "the original value of" some access path (i.e., a property of a property [etc] of the global object). In Table 7, look at the blank cells in the "Global Name" column. Of course, we can just make up names for those (as the current spec has), but we might want to visually distinguish between made-up names and 'real' access-paths, so people don't mistake one for the other. |
@annevk: Ah, thanks, I was trying to think of examples just in the ES spec (not paying enough attention when @littledan said "needed for export"). |
This doesn't address that use case due to external dependencies, which are probably useful to know about when you're working on a JavaScript engine. |
So why were these added to Table 7? The table is only intended to contain preallocated built-in object that need to explicitly referenced by the specification. If entries like these have been added because of a misunderstanding of the purpose of Table 7, then those entries should be removed. If they are there because they are needed by host environments, then they should probably be tagged as such in the table. However I'm actually a bit dubious of host requesting that we add entries to this table. They may be needed by host in a few cases, but I'd like to see some specific uses. |
@ljharb I agree that factoring out abstract algorithms would only handle some of the usages, but it would handle all the ones in this PR. That would allow this particular issue to make progress, while GetIntrinsic can be considered as a separate cleanup. |
You can find IDL usage of %ArrayProto... at https://heycam.github.io/webidl/#es-iterable. That does suggest to me those cannot simply become an abstract operation. The same probably goes for those added in this PR? (The Infra example I linked earlier on parsing JSON could easily become an abstract operation I think.) |
In #1012 (comment) I proposed an abstract operation for JSON parsing but #1013 ended up using the intrinsic per #1013 (comment) |
OK, if we consider adding more % things cleaner than abstract algorithms, then there should be no problem landing this PR as is. |
@jmdyck %isNaN% (and the other function properties of the global object) were added, so they can be accessed in SetDefaultGlobalBindings. |
Ah, right. In fact, if those 'top-level' object property values aren't in Table 7, then CreateIntrinsics won't even "know" to create them in the first place. |
Hopefully #1376 reduces the need for many of these additions. |
These will be helpful in solving whatwg/webidl#254.