[webkit-gtk] GObject API for JavaScriptCore

tevaum at gmail.com tevaum at gmail.com
Tue Oct 18 06:29:10 PDT 2016


Em seg, 17 de out de 2016 às 14:24, Carlos Garcia Campos <cgarcia at igalia.com>
escreveu:

> El lun, 17-10-2016 a las 12:37 +0000, tevaum at gmail.com escribió:
> >
> >
> > Em seg, 17 de out de 2016 às 04:31, Carlos Garcia Campos <cgarcia at iga
> > lia.com> escreveu:
> > > El lun, 10-10-2016 a las 01:19 +0000, tevaum at gmail.com escribió:
> > > > Hello, everyone.
> > >
> > > Hi,
> > >
> > > > Some background first: my name is Estêvão and every now and the I
> > > try
> > > > to contribute to Gnome Web, AKA Epiphany. First time was back in
> > > > 2010. After the migration of Epiphany to WebKit, it stopped
> > > > identifying feed links on pages. I had to dig into JavaScriptCore
> > > to
> > > > call JavaScript functions to check for feed links on pages. DOM
> > > > bindings were only in TODO by then. Now what I need to do is a
> > > little
> > > > bit different, but also involves JavaScriptCore. We need to
> > > bridge
> > > > between JavaScript and C code so that an about page can be able
> > > to
> > > > list URLs to display. I was chocked that up to now JavaScriptCore
> > > is
> > > > untouched. So I started thinking about how could a GObject
> > > binding to
> > > > JSC be implemented.
> > > >
> > > > The proposal:
> > > >
> > > > I'm thinking about creating GObjects to warap JSC objects. For
> > > > instance: GJSCContext wrapping JSContextRef, GJSCObject wrapping
> > > > JSObjectRef and so on.
> > >
> > > We talked during the web engines hackfest about adding a GLib
> > > wrapper
> > > for JSC, not necessarily a 1 to 1 wrapper from JSC object to GLib
> > > objects, though.
> > >
> > > >  I implemented a POC of the API and a simple client to make my
> > > > intentions clearer. It's available on https://github.com/tevaum/j
> > > sc-
> > > > bindings.
> > >
> > > Thanks for working on this!
> > >
> > > > With that *not-so-gobject* partial API the client is able to
> > > bridge
> > > > javascript functions to native C callbacks and to execute
> > > javascript
> > > > code from C. Also the C function returns an array to the
> > > javascript
> > > > code. An example of error handling is also shown.
> > >
> > > I think error handling is a bit different in this case, we probably
> > > need a special way to handle JS exceptions.
> > >
> > > > I think that we have to start simple and add stuff incrementally,
> > > > based on what's already being used/requested by people. Please
> > > take
> > > > your time to dig into the example code provided, ask questions
> > > and
> > > > poit directions, so that we can buld a better WebKitGTK+.
> > >
> > > I agree with the idea of starting simple and going step by step,
> > > but
> > > before designing a new API there are a set of general things we
> > > should
> > > decide, and the most important thing, we should know what we want
> > > this
> > > new API to be used for. I think the API should allow:
> > >
> > >  * Easily run javascript snippets from C code in a web extension.
> > >  * Interact with javascript contexts, retrieve existing JS values
> > > in
> > > the context to the C code, and add values from C to the javascript
> > > context.
> > >  * Easily expose full objects to javascript
> > >
> > > That would cover the main uses cases, replacing the dom bindings
> > > and
> > > injecting custom code to JavaScript.
> > >
> > > Regarding the general things we should decide:
> > >
> > >  * Naming: we don't need a name for the library because it will be
> > > part
> > > of libjavascriptcoregtk (gtk is for gtk port, not because it uses
> > > gtk
> > > at all), but we need to use apublic header and a common prefix for
> > > methods and types. In your POC you are using javascript.h as the
> > > header
> > > name, jscore prefix for methods and GJSC for types. The API should
> > > be
> > > consistent in this regard.
> > >
> > >
> >
> > Yes, I really messed up the namespaces :P What about using
> > javascriptcoregtk.h for the header, JSCoreStuff for the objects and
> > jscore_stuff for the methods? Or maybe jsc-gtk.h JSCStuff for the
> > objects and jsc_stuff for the methods?
>
> We don't use gtk in any of our public headers, so maybe <jsc/jsc.h>,
> JSCFoo, jsc_foo. What do other people think?
>
> > >  * Memory management: this is very important to decide how to
> > > declare
> > > your objects, they could be GObject, boxed types with ref counting,
> > > etc. Note that javascript objects are garbage collected, so it's
> > > very
> > > important to have mechanisms, to prevent wrapped object from being
> > > destroyed by the garbage collector if we still have a wrapper
> > > alive.
> > > So, we will probably have to protect all js object when wrapped,
> > > which
> > > means API use will always have to manually unref every single
> > > wrapper.
> > > We might want to make it easier by making out wrappers initially
> > > unowned, for example. There might be cases in which we want to
> > > wrapper
> > > to be automatically destroyed when the wrapped object is garbage
> > > collected too. We need to take into account all these cases when
> > > designing the API.
> > >
> >
> >  I think that boxed types are the best, because we can ref-count them
> > but don't get the overhead of gobject inheritance, remembering it's
> > just a wrapper...
>
> It doesn't need to be just a wrapper, because to wrap the JSC API you
> can just use the existing API. As I said, this depends on how we design
> the value object for example, if we use a different subtype for every
> value type, we definitely want to use GObjects. I really don't think
> there's that much overhead in using GObject, compared to boxed types.
> And it also depends on whether we want to use floating references,
> especially for the JSCValue it could be interesting to make it
> initially unowned.
>
>
Well... I don't really see a point on having subtypes for every kind of
value... maybe code maintainability, but I don't think this will be hurt if
we use only one type for values (yet). Feel free to convince me though. And
it's a good idea to make JSCValues initially unowned.


> > >  * Error handling: I'm not sure GError is enough to handle js
> > > exceptions. They can happen at any time and have additional
> > > information
> > > like line number, column, etc. that can't be represented by GError.
> > > The
> > > Objc API allows to set a callback per context to handle the
> > > exceptions.
> > >
> >
> > We can use a boxed type here too (simpler) or subclass GError to add
> > the details...
>
> I wouldn't use GError, but a custom exception object (boxed type or
> whatever), because it's not that we want extra info, but that maybe we
> don't really need the error code and quark.
>
> > > I would start the API with the wrappers needed to setup a js
> > > context
> > > and then the JSValueRef wrapper with methods to set an retrieve
> > > simple
> > > values (string, bool, number, array, object/dictionary, date),
> > > leaving
> > > the handling of custom objects out for now. We could probably use a
> > > bug
> > > report or a dedicated thread in this list to decide about this
> > > specific
> > > part of the API (whether we want to expose it as a single Value
> > > type or
> > > have a different type per value type, whether to use GObjects or
> > > boxed
> > > types, whether to make it initially unowned, etc.)
> > >
> >
> > I'll wait for your comments on the namespace and types to open that
> > bug report. This way, I can upload the initial patch.
>
> Ok, note that it's not just me, for public API in WebKitGTK+ we hace a
> rule that it needs to be approved by two reviewers, so maybe you want
> to wait ot hear the opinion of other people. Also, I would at least
> send a proposal here with the types you are going to add and propotypes
> of methods before spending too much time with the actual
> implementation, just in case.
>

So, considering your previous comments, we can do something like this for a
start:

Objects:
o JSCContext
o JSCValue
o JSCObject
  * JSCError (JSCArray, JSCDate and other stuff should come here too)

Methods:
JSCContext* jsc_context_new();
JSCObject* jsc_context_get_global_object(JSCContext*);
JSCValue* jsc_context_evaluate_script(JSCContext *, gchar* script,
JSCError* err);
JSCValue* jsc_value_new_string(JSCContext*, gchar *value);
JSCValue* jsc_value_new_boolean(JSCContext*, gboolean value);
JSCValue* jsc_value_new_number(JSCContext*, double value);
gboolean jsc_value_is_string(JSCValue*);
gboolean jsc_value_is_boolean(JSCValue*);
gboolean jsc_value_is_number(JSCValue*);
gboolean jsc_value_is_object(JSCValue*); //or maybe
jsc_object_new_from_value
gchar* jsc_value_get_string(JSCValue*);
gboolean jsc_value_get_boolean(JSCValue*);
gdouble jsc_value_get_number(JSCValue*);
JSCObject* jsc_value_get_object(JSCValue*); //or maybe
jsc_object_new_from_value
JSCObject* jsc_object_new(JSContext*);
gboolean jsc_object_has_property(JSCObject*, gchar* property_name);
JSCValue* jsc_object_get_property(JSCObject*, gchar* property_name);
void jsc_object_set_property(JSCObject*, gchar *property_name, JSCValue*
property_value);
gboolean jsc_object_delete_property(JSCObject*, gchar* property_name);

Implementing this API will let the client execute javascript, retrieve
values returned from it, create new values and inject them as global object
(window) properties. Is this enough for a start? Gratton and others, which
kind of stuff do you need to do with JSC?

One think is a little fuzzy for me. It's

> > > I think we can start adding the API to the source code without
> > > enabling
> > > it in production builds, nor installing the headers until it
> > > reaches a
> > > mature enough state. As with the GTK+ public APIs, the whole API
> > > should
> > > be covered by unit tests and all patches adding/modifying the
> > > public
> > > API should include a unit test.
> >
> > Agree with that. By the way, where will we put the new files? in
> > Source/JavascriptCore somewhere or in a subfolder inside
> > Source/WebKit2/WebProcess/InjectedBundle/API?
>
> This will be used by WebKit injected bundles, but it's an independent
> API that could be used by building only jsc. The API should be in
> Source/JavascriptCore/API/glib and the tests could be added to
> Source/JavaScriptCore/API/tests/glib or
> Tools/TestWebKitAPI/Tests/JavaScriptCore/glib.
>
> >  Also I would appreciate if you point me some example unit tests and
> > API documentation.
>
> All our tests are in Tools/TestWebKitAPI, see the gtk directories. We
> could use a similar infrastructure based on gtester for JSC.
>
> For more general rules take a look at:
>
> https://webkit.org/getting-started/#contribute
> http://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
>
> We will use mostly the same rules of the WebKit2 API for the JSC one.
>
> Thanks for this info. I'll check them all  :]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-gtk/attachments/20161018/747cbf22/attachment-0001.html>


More information about the webkit-gtk mailing list