Skip to content
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

Should we really include all the intrinsics? #48

Closed
domenic opened this issue Feb 16, 2017 · 8 comments · Fixed by #229
Closed

Should we really include all the intrinsics? #48

domenic opened this issue Feb 16, 2017 · 8 comments · Fixed by #229

Comments

@domenic
Copy link
Member

domenic commented Feb 16, 2017

There are a couple interesting problems with the current approach of copying all the intrinsics from table 7:

  • Membership in the list varies depending on whether 262, and other specs (such as HTML), need a copy of the intrinsic at some later time. For example, entries like ObjProto_toString and ObjProto_valueOf are not at all fundamental intrinsics (compared to e.g. Object.prototype.hasOwnProperty), but exist in the table simply because other specs need them. Similarly, we have a long-outstanding issue to formalize JSON-parsing/serializing in the web platform, which will likely lead to adding JSON_parse and JSON_serialize intrinsics. I don't think we've run into a case of the table shrinking over time yet, but that also seems plausible, e.g. if a spec is refactored to no longer need such a reference, then we might remove it from the table.
  • At least one upcoming intrinsic, %AsyncFromSyncIteratorPrototype%, is really just a spec device, which you cannot observe through the engine. Exposing it through Realm APIs would preclude implementations that never reify that prototype.

Neither of these is a showstopper, but they do imply to me that maybe copying table 7 is not the right move. Instead perhaps we should be looking for what the actual use cases for the intrinsics are and trying to craft something based on that. In particular I'm skeptical that intrinsics provides any value over stdlib.

@caridy
Copy link
Collaborator

caridy commented Feb 16, 2017

The membership is probably related to #22 as well, and it is definitely an area that requires some brainstorming.

As for the second part, I will let @erights to comment, but in all other cases, those prototypes are exposed to user-land somehow (e.g.: via prototype chain when constructing an iterator), and even though those are not accesible via a global, the implementation must reify them.

I'm skeptical that intrinsics provides any value over stdlib.

They are very different, and not all the intrinsics are available via stdlib descriptors, which by itself will be very alien to look into the descriptor's value to reach into %Array% for example. But nevertheless, the main problem is how can the owner of the realm, and master of the universe, access %ArrayPrototype% without exposing intrinsics? you can't because using the prototype chain is subject to the state of the realm, since users might have changed it.

@domenic
Copy link
Member Author

domenic commented Feb 16, 2017

The owner of the realm can access stdlib.Array.prototype before he gives a reference to it to anyone else.

@caridy
Copy link
Collaborator

caridy commented Feb 16, 2017

The owner of the realm can access stdlib.Array.prototype before he gives a reference to it to anyone else.

Almost, it is stdlib.Array.value.prototype because stdlib.Array is a descriptor. Additionally, there is the problem of inheritance, you might be inheriting from a class that provides only a subset of the stdlib. And yes, sure, you can probably figure a way to cache them, but what about %ArrayIteratorPrototype%? Again, intrinsics is about convenience by giving you access to the intrinsics directly.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2017

Are there any intrinsics that aren't somehow accessible from the global object at realm creation time? If so, which are they?

@domenic
Copy link
Member Author

domenic commented Feb 16, 2017

You can easily get access to %ArrayIteratorPrototype% using similar mechanisms.

Again, my point is that we should refocus on use cases. So far I've seen you implicitly express the use cases of:

  • Accessing intrinsics in subclasses which have censored access to the stdlib, but not censored access to intrinsics
  • Accessing intrinsics with less typing than going through stlib.

My claim is that neither of these use cases is very compelling, and I'd like to see some substantive use-case focused discussion to address that point and justify the inclusion of intrinsics in the spec.

@jfparadis
Copy link
Collaborator

Do we really need to expose the intrinsics, 'stdlib', and do we need the init() callback?

Exposing the intrinsics can easily cause identity discontinuities:

class FakeWindow extends Realm {
  init() {
    super.init();
    let global = this.global;
    global.document = new FakeDocument(...); 
  }
}

const r = new FakeWindow();
r.evaluate("document instanceof Object"); // false

For most use cases, we need to decide if we create:

  1. a new "root real" with a fresh set of intrinsics
  2. a new "compartment realm" which inherit intrinsics

Then, all patching can be done using evaluate():

class FakeWindow extends Realm {
  constructor() {
    super();
    this.evaluate(documentShimSource);
  }
}

const r = new FakeWindow();
r.evaluate("document instanceof Object"); // true

@erights
Copy link
Collaborator

erights commented Jul 4, 2018

As we note at #52 (comment) and elsewhere, we should drop the intrinsics api from the realms proposal completely. It is a dangerous way to customize a realm.

@littledan
Copy link
Member

It seems like intrinsics is still part of this API, see https://github.com/tc39/proposal-realms/blob/master/spec/index.emu#L110 . Is there any plan to revisit this issue? Seems important to come to a resolution on one way or another before Stage 3. (I like the conclusion reached earlier in this thread to remove the API.)

littledan pushed a commit to littledan/proposal-realms that referenced this issue Feb 28, 2020
caridy pushed a commit that referenced this issue Feb 28, 2020
* Normative: Remove intrinsics() method from spec

Closes #48

* Remove intrinsics() method from README
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants