This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 20836 - What happens when a dictionary references itself?
Summary: What happens when a dictionary references itself?
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebIDL (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Cameron McCormack
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-31 10:54 UTC by François REMY
Modified: 2013-02-01 01:09 UTC (History)
3 users (show)

See Also:


Attachments

Description François REMY 2013-01-31 10:54:36 UTC
Let's imagine the following dictionary:
[[
    dictionary LinkedList {
        any value;
        LinkedList? next;
    }
    
    void testConversion(LinkedList data) {
        /* do nothing */
    }

    LinkedList testBackConversion() {
        /* return a node that references itself as next node */
    }
]]

What happens in this situation:
[[
    var p={};
    p.value=true;
    p.next=p;

    testConversion(p);
]]

What happens if the same situation happens but is created in the WebIDL world and has to be converted back a JavaScript object?
[[
    var p = testBackConversion();
]]

http://dev.w3.org/2006/webapi/WebIDL/#es-dictionary

[[
Let value be the result of converting idlValue to an ECMAScript value.
]]
Comment 1 Boris Zbarsky 2013-01-31 17:14:01 UTC
Is this fundamentally different than a dictionary that simply goes into an infinite loop in JS when you try to get the .next?

I mean, from an implementor's point of view it might be because they'd have to detect the different situation, but conceptually?
Comment 2 François REMY 2013-01-31 17:18:00 UTC
It's not an opinion or a bug, it's just a question in fact ;-)

My question is: should we keep reference of objects using a weakmap or a reference table or is it fine to simply loop forever (the browser will ultimately kill the script)?

What do browser do today (even if the situation don't happen, what would they do if I added the necessary interface but changed no other code whatsoever)?
Comment 3 Boris Zbarsky 2013-01-31 17:41:37 UTC
It sort of depends on the IDL used.

The IDL in comment 0 is I believe not actually valid WebIDL.  See the part of http://dev.w3.org/2006/webapi/WebIDL/#idl-dictionaries starting "The type of a dictionary member MUST NOT include the dictionary it appears on".  We don't actually seem to enforce those rules in Gecko yet, but we enforce something similar so if you try to use that IDL in Gecko, you get:

  TypeError: Loop in dictionary dependency graph

from the code generator for the bindings.

You could get around the spec restriction by doing something like this:

  dictionary L1 {
    L2 next;
  };
  dictionary L2 {
    L1 next;
  }

but that will hit the same situation as above in Gecko (and it's possible the spec meant to disallow this too but just failed to).
Comment 4 François REMY 2013-01-31 17:59:00 UTC
Okay, thanks for the check. Actually, it makes sense. 

However, I'm still not completely secured: even if we add something smart enough to restrict value-type loops in the WebIDL graph, you can't avoid the 'any' type to cause the same issue, right?

Are there any dictionary out there with an 'any' or 'object' field? If not, we could simply mark it invalid, too and I can just decide that I can safely ignore this problem as it's impossible to get into this situation.

In fact, I can do it even if it's actually possible but I would feel dirty ^_^
Comment 5 François REMY 2013-01-31 18:23:11 UTC
Sorry, it doesn't make sense. 'any' and 'object' may indeed contain a reference to the dictionary but it will be stored by reference so that should not be a problem.

So, if we just add some prose to ask to avoid loops in the dictionary type graph, it should be all right.
Comment 6 Cameron McCormack 2013-02-01 01:09:02 UTC
I did mean to disallow mutually referential dictionaries like this.  I've added this item to the list below "The type ... MUST NOT include ...":

  * the type is a dictionary, one of whose members or inherited members has
    a type that includes D