Re: Structs in gobject-introspection + Javascript
"Havoc Pennington" <[email protected]> Sat, 8 Nov 2008 18:14:54 -0500
| Newsgroups | gmane.comp.gnome.language-bindings |
|---|---|
| Message-ID | <[email protected]> |
Hi, On Sat, Nov 8, 2008 at 5:07 PM, Owen Taylor <[email protected]> wrote: > [ Sorry for the long cc: list. Do we need [email protected]? ] It would be pretty low-traffic, but maybe so. I guess it could include both seed and gjs. As long as nobody minds, maybe it's simpler to just use language-bindings, since language-bindings is so low-traffic anyway. Anyway, no strong views. > Here's what I came up with. An actual attempt to implement structures > would likely run into issues I haven't thought of here. Probably nothing too major, except for writing the actual struct-offset-computation code. > 1. Structs are supported if they are: > > - Have no pointer fields. (They can have nested structures{1} and union > fields). Call these simple structures. > > Or: > > - Are registered as boxed types with GObject > > Note that some structures, such as GdkRectangle or GdkColor are both > boxed and simple structures. {2} Is it desirable to support not-registered-as-boxed structs, or could we just register them all as boxed? Not sure it is materially harder to support non-boxed types, so maybe it doesn't matter. One consideration is that some boxed, maybe GdkCursor (don't remember the examples) ref rather than copy in their copy function. I don't know if it ever makes a difference. I believe the rule is that if it's refcounted and mutable, it should be a GObject to be nicely bindable. Fixing GObject to avoid its current overhead (as discussed on whichever bug it is) would help here. > 2. When a structure is passed from C to Javascript, there is an implicit > copy made. Thus: > > var some_global; or "let someGlobal" ;-) > 4. In any place a a simple structure is expected, any other object that > has properties for all the objects fields can be used. So, you can do: > > window.invalidate_rect({ x: 5, y: 5, width: 100, height: 100 }, true); An interesting question this raises is whether you would ever bother (for simple structs) with the current boxed.c type of implementation where the JS object contains a C struct. I would say no; when you copy, just create a plain JS dict with the appropriate properties. So there would be no JSClass corresponding to simple structs. For boxed structs, this does create a strange multiple-codepaths situation, if the boxed struct is simple also (is not opaque). For opaque boxed structs, the JSClass wrapping a C pointer is clearly necessary. Perhaps implementation-wise, the issue is whether the struct is opaque or not... whether having the values of all struct fields is equivalent to having the struct. Not whether the struct is boxed. If the struct is not opaque, then there's never a need for a special JSClass, just always map as a plain JS object. if the struct is opaque, then we need a JSClass wrapping a boxed type. Is it possible to have a boxed type with some non-opaque / visible fields, that still must be treated as boxed and not just copied by value? GdkEvent I guess is an example since copy by value breaks? But for GdkEvent, do we want to allow a plain object with the appropriate fields to substitute? I'm wondering if we can avoid multiple codepaths, where to marshal the args to something that takes struct Foo, we have to handle both a wrapper-object-for-C-struct and a random JS object. (Though, just doing one codepath and always using JS_GetProperty would work, it would be a lot less efficient than getting the wrapped C struct and then memcpy'ing it in the case where the wrapped struct exists) Just thinking out loud, don't know > copy() - returns a new object that is a copy of this object [2] clone() would be the usual name for this in JavaScript I think, various xpcom objects use clone() and prototype.js adds Object.clone I don't think SpiderMonkey's Object class has clone() already but maybe it does. > set() - assigns a value of another object of the same type to the > object [3] Does imports.lang.copyProperties() always do the same thing? If someone passed in a dict as a struct, it would not have these methods. That could be a little surprising; perhaps it is cleaner if non-opaque structs are always just plain objects, and have no special methods at all. Are copy() and set() really more useful on a rectangle than they would be on any other JS dictionary? Under what circumstances would some JS code know it had a special GdkRectangle proxy with copy() and set(), vs. just a dictionary with x/y/width/height fields? > So, equivalent to the size-request example above you can do: > > widget.connect('size-request', > function(widget, request) { > request.set({ width: 100, height: 50 }); > }); In the size-request case, what is going on with the copying? Do we copy the Requisition, pass it to the handler, then set the original requisition back to the copy's new values? > [1] Or is it better to do out structure parameters like you would do out > integer parameters - as a return value or an array of return values? > I generally like the suggested method better because it corresponds to C > code and to some of the existing GObject language bindings. It seems like it's necessary to map out how some contrived method signatures would work, like: struct Foo; Foo* foobar(out Foo, out int, out Foo) Are we saying that some out params (structs) are done in JS by passing in dictionaries, and some are return values, so: let foo1 = {}; let foo2 = {}; [rval, intOut] = foobar(foo1, foo2); And fields in foo1, foo2 would get set? It seems a bit simpler to me if we just map all "out" params as return values (which is how it works now, iirc): [rval, foo1, intOut, foo2] = foobar(); > {2} There is no way to tell distinguish a a simple structure > registered as a boxed from a boxed object with internal private state. This may reinforce the idea that opaque vs. plain old data is the real distinction, at least for certain purposes, rather than whether it's registered None of the above terribly thought out, just figured replying quickly would be helpful. Havoc _______________________________________________ language-bindings mailing list [email protected] http://mail.gnome.org/mailman/listinfo/language-bindings