On Tue, Mar 22, 2016 at 11:05 AM Giovanni Campagna <
scampa.giova...@gmail.com> wrote:

> Ok, let's try a factual response...
>

Oops; that will teach me to check first and not try to answer from memory
:-/

>
> On Tue, 2016-03-22 at 17:24 +0000, Andrea Giammarchi wrote:
> > > There is not even any Gio.LocalFile known to JS.
> >
> > ```js
> > const a = imports.gi.Gio.File.new_for_path('./a.js');
> >
> > // here the "now known to JS" Gio.LocalFile.prototype
> > Object.getPrototypeOf(a).shenanigans = true;
> >
> > const b = imports.gi.Gio.File.new_for_path('./b.js');
> >
> > // all instances affected indeed
> > print(b.shenanigans); // true
> > ```
> >
> > > It's not exposed in the GIR file, so there is never a prototype
> > object created in the first place
>
> Yes, there is a prototype object created. Every JS object with custom
> behavior has a custom prototype object in SpiderMonkey, that's just how
> it is.
>
> This prototype object is "GLocalFile", and it's stored in an invisible
> object that exists just to reference it, as well as other hidden
> classes that appear through GType but not through introspection.
>
> It's supposed to be mostly invisible, but it's unavoidable.
>
> > There is:
> >
> > ```js
> > const a = imports.gi.Gio.File.new_for_path('./a.js');
> > // here the *shared* Gio.LocalFile.prototype
> > Object.getPrototypeOf(a);
> > ```
> >
> > > In GJS, you can check if an object implements an interface with
> > myObj.constructor.implements(Gio.File).
> >
> > That's good to know, thanks, yet if you read first messages of this
> > thread it was about patching upfront and not at runtime.
> > I understand I can find at runtime pretty much anything I want, but
> > since there is an introspection ability, why are there undocumented
> > instances around with undocumented prototypes?
> >
> > Or better, why `Gio.File.new` creates something unrelated with
> > `Gio.File.prototype` or `Gio.File` methods ?
> > Since this super secret thing is easily leaked, why not fixing this
> > instead of saying that it shouldn't be known?
>
> You can't fix that.
>
> The truth is, Gio.File is a lie.
> Indeed, Gio.File.prototype.replace_contents !==
> (Gio.File.new_for_path('/foo')).replace_contents
>
> What it means is that Gio.File is an object that exists only to hold
> methods that quack like the actual interface methods, if you call them
> explicitly with say
> Gio.File.prototype.replace_contents.call(file, "bla")
> , but has nothing to do with the interface methods exposed on each
> object.
>
> The reason for this is that prototype inheritance is single, but a
> GObject class can have multiple interfaces, so there is no good place
> to put Gio.File.prototype on the prototype chain from file to
> Object.prototype (in a way that's generic and consistent with say,
> Gtk.Label and Gtk.Buildable).
> So what happens is that every class that also implements an interface
> will resolve all interface methods on its own prototype.
>
> In the Gtk.Label case, Gtk.Label implements Gtk.Buildable and
> Gtk.Widget implements Gtk.Buildable, both visible in the GIR, which
> means
> Gtk.Label.prototype.hasOwnProperty('custom_tag_start') === true
> and
> Gtk.Widget.prototype.hasOwnProperty('custom_tag_start') === true
>
> In the GLocalFile case, GLocalFile implements Gio.File, and we know
> that from GType at runtime, so
> window.<invisible
> name>.GLocalFile.prototype.hasOwnProperty('replace_contents') === true
> but you don't know that unless you poke at Object.getPrototypeOf
>
> Yes, this is very awkward if you monkey patch prototypes, but that's
> just how it is.
>
> > The reason I've asked is that I've discovered there are hidden
> > classes the GIR won't tell me, doesn't know, but **are** on my way.
> >
> > > I don't believe Spidermonkey would support overloading instanceof
> > for this
> >
> > `instanceof` is the most easily "overloaded" ( not actually
> > overloaded, it just checks
> > `rightSide.prototype.isPrototypeOf(leftSide)` ) operator which is why
> > I am asking if this would ever be solved.
>
> Now, if we tell a lie, we should at least be consistent about it, and
> that's why
> Gio.File.new_for_path('/') instanceof Gio.File
> should return true
>
> Checking the prototype would not work, but instanceof can be overloaded
> "properly", because after all we have access to the C API of SM and we
> can do what we want.
>
> Indeed, that's https://bugzilla.gnome.org/show_bug.cgi?id=587030
> which has had patches for a while and probably needs a rebase, but
> would make the Gio.File lie less visible to programmers.
>
> Hope this clarifies the situation, and cheers,
>
> Giovanni
_______________________________________________
javascript-list mailing list
javascript-list@gnome.org
https://mail.gnome.org/mailman/listinfo/javascript-list

Reply via email to