[webkit-gtk] GObject API for JavaScriptCore

Carlos Garcia Campos cgarcia at igalia.com
Tue Oct 18 10:07:24 PDT 2016


El mar, 18-10-2016 a las 13:29 +0000, tevaum at gmail.com escribió:
[...]
> > 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.

I'm afraid it works the other way around :-) you have to convince us
that using boxed types is better, or prove that the GObject overhead is
so high that it's worth not using them. We could implement the desired
features for a boxed type (ref counting, floating refs, weak refs,
etc.) but we would be reinventing GObject in the end. Note that we can
have a single JSCValue for everything but still make it a GObject
instead of a boxed type.
 
> > > >  * 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)

Why is Object special? So, we use a single JSValue for everything
except Object? I think we should be consistent here. I know that's what
the C API does, but this is what I meant when I said that our API
doesn't necessarily need match the C API 1 to 1.

And then JSCError is also a JSCObject? why is this a different object
too? I think it should be named JSCException, btw.

> Methods:
> JSCContext* jsc_context_new();
> JSCObject* jsc_context_get_global_object(JSCContext*);

If we add convenient methods to JSCContext to deal with the global
object we can leave this for now. For example, the Objc API allows to
do something like this:

context["foo"] = @"bar";

This means, create a string value with "bar" contents and set it to the
global object of context as property "foo". And the same to get a
value;

JSValue *foo = context["foo"];

This is super convenient, we can't do the same in C, but we can still
add convenient methods to do that, for example:

jsc_context_set_object (context, "foo", jsc_value_new_string ("bar"));
JSCValue *foo = jsc_context_get_object (context, "foo");

Note that we can pass the returned value of jsc_value_new_string (or
jsc_string_new if we use subtypes) if we make them initially unowned
and the context consumes the floating reference.

> JSCValue* jsc_context_evaluate_script(JSCContext *, gchar* script,
> JSCError* err);

Note that evalueScript is not the only function that can raise js
exceptions, other methods like jsc_value_ge_string() for example, can
also raise a exception. Adding a GError like parameter to all our API
methods wouldn't be very convenient, and if a function changes from not
raising exception to raise exceptions, we would need to change the API
to add the error parameter. Again, following what Objc API does, we
could add a exception handler to the JSContext that receives the
JSCException object, and assume that any API method can raise a
exception in the context.

> JSCValue* jsc_value_new_string(JSCContext*, gchar *value);
> JSCValue* jsc_value_new_boolean(JSCContext*, gboolean value);
> JSCValue* jsc_value_new_number(JSCContext*, double value);

I think we should have different methods for number new_int32,
new_uint32, new_double

> gboolean jsc_value_is_string(JSCValue*);
> gboolean jsc_value_is_boolean(JSCValue*);
> gboolean jsc_value_is_number(JSCValue*);

All is methods are not needed if we use subtypes, we would have
JSC_IS_STRING, JSC_IS_BOOLEAN, etc.

> gboolean jsc_value_is_object(JSCValue*); //or maybe
> jsc_object_new_from_value
> gchar* jsc_value_get_string(JSCValue*);

In this case, the getters are not returning an internal value stored,
that's why you return gchar* and not const gchar* I guess. If we use a
single JSCValue type, I would call the methods to instead of get, in
this case folloiwing the C API:

JSValueToStringCopy() -> jsc_value_to_string()

if we use subtypes, then get would make more sense probably

> 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);

I would leave the JSCObject for now. A first patch could just add and
retrieve simple values to the context.

I still miss the details about the memory management. Does an object
created with jsc_value_new protect the value from being garbage
collected? how do you plan to handle that?

> 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  :]
> 
> _______________________________________________
> webkit-gtk mailing list
> webkit-gtk at lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-gtk
-- 
Carlos Garcia Campos
http://pgp.rediris.es:11371/pks/lookup?op=get&search=0xF3D322D0EC4582C3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 191 bytes
Desc: This is a digitally signed message part
URL: <https://lists.webkit.org/pipermail/webkit-gtk/attachments/20161018/f2a8b90e/attachment.sig>


More information about the webkit-gtk mailing list