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

dart2js: Object is using mixed up calling conventions #8942

Closed
rakudrama opened this issue Mar 6, 2013 · 9 comments
Closed

dart2js: Object is using mixed up calling conventions #8942

rakudrama opened this issue Mar 6, 2013 · 9 comments

Comments

@rakudrama
Copy link
Member

There are four calling 'conventions':

­1. direct: receiver.foo(arg)

And three variations of passing an explicit receiver:

­2. intercepted: interceptor.foo(receiver, arg)

The interceptor and receiver are (potentially) different objects; the receiver is passed as the first parameter and its receiver is passed as the 'this' parameter.

­3. interceptor: receiver.foo(receiver, arg)

Used in a context where all possible receivers are self-intercepting, but the method may be reached by an interceptor or a self-intercepting class. Example: a method from a mixin placed on a plain class and an intercepted class will need a correct explicit receiver, even if we know the receiver is a plain class.

­4. ignored-explicit-receiver: receiver.foo(0, arg)

Smaller call site used when the set of 'foo' implementations are all for self-intercepting classes and access the receiver via 'this'.

­3 is a current optimization of #­2 when no genuine interceptors are possible.

­4 is a future optimization of #­3.

By convention, ignored-receiver methods rename the 'receiver' first argument to '_' and don't use it.

Object seems very confused:

$$.Object = {"": ";",
  //// $eq names the receiver but ignores it!!!
  $eq: function(receiver, other) {
    return this === other;
  },
  //// get$hashCode has an ignored-receiver name, but uses it!!!
  get$hashCode: function() {
    return $.Primitives_objectHashCode(
);
  },
  toString$0: function() {
    return "Instance of '" + $.S($.Primitives_objectTypeName(
)) + "'";
  }
};

We need to decide if Object can subclassed by an interceptor class or by a regular class.
If it is both, then we can't use convention #­4 for methods on Object, and we need to fix $eq and whatever is causing the incorrect naming of the 'receiver' parameter.

@DartBot
Copy link

DartBot commented Mar 6, 2013

This comment was originally written by ngeoffray@google.com


It's actually not mixed up and deliberate. In general, methods in Object should use the first argument, because the receiver might be a primitive. Because we know operator== will be in all interceptor classes (the emitter manually adds them), we can have the operator== just use 'this' instead. See builder.dart: buildMethod.

But it's fine to use the first argument for operator==.

@rakudrama
Copy link
Member Author

You will agree the naming is inconsistent with use?

The emitter can't manually add for all 500 DOM types - too much code.
The DOM types at least will need a common superclass.
Might as well share 'class Interceptor' with the other interceptors and have Interceptor.$eq test 'receiver' and have Object.$eq test 'this' to enable #­4.

@DartBot
Copy link

DartBot commented Mar 7, 2013

This comment was originally written by ngeoffray@google.com


That sounds good to me. Object has always been in this akward state with the interceptors v1, and interceptors with new calling conventions. I haven't done a great job on making it consistent, but that's mostly because I knew the DOM types would come in the game :), and would most probably bring up their own requirements.

@kasperl
Copy link

kasperl commented Apr 22, 2013

Added this to the Later milestone.

@kasperl
Copy link

kasperl commented May 23, 2013

Added TriageForM5 label.

@kasperl
Copy link

kasperl commented May 28, 2013

Removed TriageForM5 label.

@kasperl
Copy link

kasperl commented Jul 10, 2014

Removed this from the Later milestone.
Added Oldschool-Milestone-Later label.

@kasperl
Copy link

kasperl commented Aug 4, 2014

Removed Oldschool-Milestone-Later label.

@rakudrama
Copy link
Member Author

All intercepted classes extend Interceptor.
The compiler validates that all methods defined on Object (toString, hashCode etc) are also defined on Interceptor. The version on Object and Interceptor differ in where they get the receiver.
NoSuchMethod stubs for interceptor calling convention methods call Object.noSuchMethod or Interceptor.noSuchMethod, which selects the correct receiver, so the stubs on Object are agnostic to the issue.

@kevmoo kevmoo removed the triaged label Mar 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants