[Bug 15986] Specify exactly how and when ECMAScript arguments are evaluated

https://www.w3.org/Bugs/Public/show_bug.cgi?id=15986

Cameron McCormack <cam@mcc.id.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|enhancement                 |normal

--- Comment #19 from Cameron McCormack <cam@mcc.id.au> 2012-03-06 04:08:58 UTC ---
Dave Herman pointed out another current use of overloads in the Typed Arrays
spec, which defines interfaces like this:

  [Constructor(unsigned long length),
   Constructor(Uint32Array array),
   Constructor(unsigned long[] array),
   Constructor(ArrayBuffer buffer,
                 optional unsigned long byteOffset,
                 optional unsigned long length)]
  interface Uint32Array ...

which would need to be rewritten as:

  [Constructor((unsigned long or Uint32Array or
                unsigned long[] or ArrayBuffer) init),
   Constructor(ArrayBuffer buffer, unsigned long byteOffset,
               optional unsigned long length)]
  interface Uint32Array ...

so we have to use a less useful argument name there.  It's also a fair bit less
clear to someone reading the IDL what the different allowable invocations are. 
Is that acceptable?  I find the top one much more readable, anyway, and if
possible I think it would be good to keep allowing it.

I should point out that if we make overload resolution look only at argument
list length that we still need to do much of the same inspections of JS values
for union types.  Step 10 and onwards of the overload resolution algorithm is
pretty much the same as the steps in
http://dev.w3.org/2006/webapi/WebIDL/#es-union.

What are the concrete bad things about the current overload resolution
algorithm?

Boris brought up the fact that it is currently invoked even when there is only
a single operation.  In off-bug discussion, I talked about the difference
between running the overload resolution algorithm and not and that I wanted to
remove the difference between these two cases so that we didn't have different
exception throwing behaviour if we introduce an overload later on.  The example
I had was that you start with this:

  void f(long x, Node n);

and say content does this call:

  f({ valueOf: function() { throw "hi" } }, window);

If we do not call the overload resolution algorithm, since there's only a
single IDL operation, the result will be "hi" being thrown, since we just do
left-to-right argument conversion.

If we then later introduce an overload,

  void f(long x, Node n);
  void f();

this means the above call would first invoke the overload resolution algorithm,
which would throw TypeError because there was no match (window isn't a Node).  


Here's another option off the top of my head: we could make it so that
arguments to the left of the one that is used to determine which overload is
selected always get converted first.  So if we start off with:

  void g(long x, Node y, Node z);

then calling

  g({ valueOf: function() { throw "hi" } }, 0, 0);

would throw "hi", and if we introduce another overload later:

  void g(long x, Node y, Node z);
  void g(long x, Window y, Window z);

then it would still throw "hi" because the steps would be:

  1. Eliminate the overloads whose arg count doesn't match.
  2. Convert the first argument.
  3. Inspect the second argument value, and use it to select the overload (or
       throw TypeError if none are appropriate).
  4. Convert the third argument according to which overload we selected.

We would need to have a restriction that all arguments to the left of the one
used to discriminate the overloads are all the same type, for a given arg
count.

This would allow us to keep the more readable overloads.

-- 
Configure bugmail: https://www.w3.org/Bugs/Public/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

Received on Tuesday, 6 March 2012 04:09:41 UTC