1. 03 Mar, 2019 1 commit
  2. 11 Feb, 2019 1 commit
    • Philip Chimento's avatar
      object: Cache field info during resolve already · dce837ce
      Philip Chimento authored
      In object resolve (lazy property definition), we define a JS property
      for a GObject field, and give the property getter and setter a key with
      which it can look up its GIFieldInfo in a cache.
      Previously, the getter and setter would look in the cache, and if the
      GIFieldInfo was not present, compute it from the object's GIObjectInfo
      and add it to the cache.
      Since resolution of a GObject field will always be followed immediately
      by either a getter or setter invocation, and we already have the
      GIFieldInfo available at the resolve step, go ahead and add it to the
      cache already, instead of discarding it and computing it again shortly
      See also: gjs#223
  3. 02 Jan, 2019 2 commits
    • Philip Chimento's avatar
      wrapperutils: Factor out Base/Prototype/Instance scheme · 6e8ad294
      Philip Chimento authored
      This generalizes the ObjectBase/ObjectPrototype/ObjectInstance classes
      from object.cpp into three template classes in wrapperutils.h:
      GIWrapperBase, GIWrapperPrototype, and GIWrapperInstance.
      We want to take up as little space as possible, so all three use the
      CRTP technique (child class as a template parameter) in order to get
      compile-time polymorphism instead of runtime polymorphism where a vtable
      would need to occupy space.
      The changes consist mostly of moving code from object.cpp to
      wrapperutils.h and renaming some methods and members to be more general.
      Since this code has traditionally been difficult to understand for those
      unfamiliar with the code base, we try to remedy this by adding
      comprehensive documentation comments in wrapperutils.h.
    • Philip Chimento's avatar
      wrapperutils: Factor out gjs_define_static_methods() · f7153d4d
      Philip Chimento authored
      The same code is repeated several times in a few different functions,
      because of there being different APIs in gobject-introspection for
      g_struct_info_get_method(), g_object_info_get_method(),
      g_interface_info_get_method(), etc. These functions had diverged
      slightly. For example, the GIInterfaceInfo version did not define static
      methods from the interface's gtype struct, while the GIObjectInfo
      version did.
      We can consolidate these, in order to prevent future divergence, using a
      policy template to provide the polymorphism.
      Unfortunately the template parameter cannot be the type of
      the introspection info (GIStructInfo, GIObjectInfo, etc.) because these
      are all typedefs for GIBaseInfo and therefore cannot be used to
      differentiate the templates. Neither can the GIInfoType tag be used as
      the template parameter, because GI_INFO_TYPE_BOXED can be either a
      GIStructInfo or GIUnionInfo. It's also not possible to just cheat and
      use the same API for each one, because the n_methods fields are all at
      different offsets in the different introspection info records.
      Therefore, we introduce InfoType::Struct, InfoType::Object, etc., as the
      template parameters for gjs_define_static_methods().
      As a result of this change, interfaces now get static methods from the
      interface's gtype struct.
  4. 21 Dec, 2018 1 commit
  5. 01 Dec, 2018 2 commits
  6. 06 Nov, 2018 1 commit
    • Philip Chimento's avatar
      atoms: Allow "symbol atoms" for keys not exposed to JS · 5c1a24ad
      Philip Chimento authored
      There are a few places where we want to have property keys that are
      well-known internally, but not available to JS code. We create "symbol
      atoms" for these, where you can get a jsid from the GjsAtoms object, but
      it refers to a JS::Symbol instead of a string.
      Previously we had two instances of this, and both were implemented in a
      different way. For "__gjsPrivateNS" we just used a string and hoped that
      nobody used that string in client code. For "__GObject__hook_up_vfunc" we
      did create a JS::Symbol and had some complicated static member in
      ObjectInstance to expose it to imports._gi. Both of these implementations
      are simplified with this patch.
  7. 30 Oct, 2018 3 commits
    • Philip Chimento's avatar
      object: Make ObjectPrototype constructor fallible · cf857bcd
      Philip Chimento authored
      ObjectPrototype has two GC hash tables whose construction is also
      fallible, so it needs to be fallible itself. The usual pattern in
      SpiderMonkey for this is to add an `init()` method that must be called
      after construction, which is fallible.
    • Philip Chimento's avatar
      js: Introduce annotations for using return values · 425b94d6
      Philip Chimento authored
      This introduces two annotations to functions. GJS_USE is a macro for GCC
      and Clang's "warn_unused_result" annotation, meaning that the return
      value of a function must not be ignored. This allows us to catch some
      cases where we are neglecting to do error checking.
      The second annotation is GJS_JSAPI_RETURN_CONVENTION which for now is
      identical to GJS_USE, but could be made into a custom annotation in the
      future which a static analyzer plugin could use to enforce further checks
      at compile time. The "JSAPI return convention" is valid on functions that
      return bool or a pointer type, and whose first parameter is JSContext*. If
      false or nullptr is returned, then an exception must be pending at return
      time on the passed-in JSContext. If true or a non-nullptr value is
      returned, then no exception must be pending.
      This commit only has the addition of the attributes, and a few fixes
      mandated by the autoformatter, so it can be reviewed "lightly".
    • Philip Chimento's avatar
      object: Make gjs_object_associate_closure() infallible · ba32a07c
      Philip Chimento authored
      The underlying ObjectInstance method can't fail, so neither should this
      one. It should just be a no-op when called on the wrong object. The return
      value was also already ignored in all callers.
  8. 13 Oct, 2018 1 commit
    • Philip Chimento's avatar
      jsapi-util: Make GjsAutoInfo more typesafe · 4d47c0ec
      Philip Chimento authored
      The types GIFunctionInfo, GIObjectInfo, etc., are just typedefs for
      GIBaseInfo. So, this template actually wasn't specialized at all,
      everything was just an alias for GjsAutoInfo<GIBaseInfo>. Instead, we
      make the GIInfoType enum value the template parameter, and do some
      validation with the tag whenever an instance takes ownership of a
      This requires a bit of extra specialization for GICallableInfo since that
      type may have more than one GIInfoType tag.
      This should provide much better type safety than the old code.
  9. 29 Aug, 2018 1 commit
  10. 17 Jul, 2018 1 commit
    • Philip Chimento's avatar
      object: Resolve properties in resolve_no_info · 12ace06a
      Philip Chimento authored
      A regression from the property cache refactor caused properties like
      Gio.NetworkMonitor.network_available to disappear. This was because
      NetworkMonitor is an interface, implemented by a non-introspectable
      class, i.e. Gio.NetworkMonitor.get_default() gives you an instance of
      GNetworkMonitorBase which does not have introspection information.
      To fix this, we iterate through all the interfaces implemented by a
      non-introspectable type, and check if the ID to be resolved is a property
      of one of them, and define it on the prototype if so. For this we factor
      out some code into separate functions, and change resolve_no_info() to
      have a parameter specifying whether to consider only methods or both
      methods and properties.
      Closes: #182
  11. 30 Jun, 2018 3 commits
    • Philip Chimento's avatar
      object: Use smaller data structure for closures · 93cf31db
      Philip Chimento authored
      Some time ago, we switched from GList* to std::set to store the list of
      GClosures associated with an object. std::set was the most time-efficient
      container, but we need to optimize for space here. std::forward_list is
      comparable to GSList.
      This reduces ObjectInstance to 96 bytes and ObjectPrototype to 192 bytes.
    • Philip Chimento's avatar
      object: Split ObjectPrototype from ObjectInstance · 4413e30d
      Philip Chimento authored
      This creates two separate classes, ObjectPrototype and ObjectInstance, so
      that we don't have to have a copy of prototype-only data in each
      ObjectInstance. This should save a lot of memory.
      There is one element common to both classes: a list of GClosures (for
      prototypes, these are vfuncs, and for instances, connected signals.)
      Since we can only create a JSClass with one private type, we use a common
      base class ObjectBase for that type. ObjectBase contains the list of
      closures and a means of distinguishing whether a particular ObjectBase
      pointer holds an ObjectInstance or ObjectPrototype. For this we use an
      ObjectPrototype pointer, which is null in ObjectPrototypes, and in
      ObjectInstances points to the associated prototype. (This scheme is
      similar to what we do in fundamental.cpp.)
      Both ObjectInstance and ObjectPrototype have an associated GObjectInfo
      and GType, but now these are stored only on the prototype.
      Note that we do not use RTTI and dynamic_cast<> because SpiderMonkey
      supports compiling both with and without RTTI. That's the reason for this
      unusual scheme with the ObjectPrototype pointer and the to_prototype() /
      to_instance() methods. dynamic_cast<> would certainly be cleaner and more
      readable, so that might be something to investigate in the future.
      This also allows moving the PropertyCache and FieldCache into
      ObjectPrototype, instead of keeping them as qdata on the GType.
      We now define separate memory counters for ObjectPrototype and
      On x86_64 with Clang, ObjectInstance was previously 128 bytes and is now
      112. ObjectPrototype was effectively 288 bytes (128 for ObjectInstance,
      plus 160 hidden bytes for the PropertyCache and FieldCache stored on the
      GType) and is now 208 bytes.
      Closes: #165
    • Philip Chimento's avatar
      object: Split file into smaller logical units · 44ed1dc0
      Philip Chimento authored
      We now have object.cpp dealing only with ObjectInstance, the JSClass for
      wrapper JS objects. Two new files are created:
      - gobject.cpp, which is the dynamic GObject types for classes and
        interfaces created in JS code.
      - private.cpp, which is the private GI native module, accessible from JS
        as `imports._gi`.
  12. 12 Jun, 2018 1 commit
    • Philip Chimento's avatar
      js: Fix return values of not-really-infallible functions · fb100c9a
      Philip Chimento authored
      While refactoring object.cpp I noticed that gjs_define_object_class()
      doesn't do proper error checking; the JSAPI functions used within it can
      throw, but it doesn't check that.
      Fixing this also had a cascade effect on
      gjs_object_define_static_methods() and gjs_define_param_class(), as well
      as some code in fundamental.cpp and repo.cpp.
      Similarly, find_vfunc_info() in object.cpp could also throw but the
      return value was never checked.
  13. 21 May, 2018 1 commit
  14. 18 Feb, 2018 1 commit
    • Philip Chimento's avatar
      context: Shut down toggle queue before dispose notify · 3fbdb373
      Philip Chimento authored
      This adds a method to shut down the toggle queue so that it doesn't
      accept any more toggles. This is intended to stop toggles happening that
      are queued from other threads while the GjsContext dispose sequence has
      already entered its final garbage collection.
      We clear pending toggles and shut down the toggle queue before chaining
      up in GjsContext's dispose function. Sending out dispose notifications
      causes all GjsMaybeOwned instances to unroot themselves, which means that
      toggles don't have much meaning after that point.
      Closes #26.
  15. 19 Sep, 2017 1 commit
  16. 23 Aug, 2017 1 commit
  17. 16 Apr, 2017 1 commit
    • Philip Chimento's avatar
      maint: Use correct mode lines in all files · 9e4169eb
      Philip Chimento authored
      I finally figured out why my highlighting was always messed up; the mode
      lines in all these files said "C" whereas they were C++ or JS files. This
      was in such a blind spot that I even copied it to new files that I had
      created in the meantime...
  18. 08 Feb, 2017 1 commit
  19. 28 Jan, 2017 1 commit
  20. 31 Dec, 2016 1 commit
    • Philip Chimento's avatar
      object: Make define_static_methods infallible · 177c8f08
      Philip Chimento authored
      Previously, gjs_object_define_static_methods() always returned true even
      if an exception was thrown, causing the exception to be swallowed. Since
      it never returned anything but true, we get rid of the return type.
      Exceptions thrown by fallible functions called within
      gjs_object_define_static_methods() are logged immediately and cleared.
      (Allowing the exceptions to propagate and be caught would potentially
      result in a GI namespace with only half its methods defined, and that
      seems undesirable.)
  21. 28 Oct, 2016 1 commit
  22. 27 Oct, 2016 1 commit
  23. 20 Oct, 2016 2 commits
    • Philip Chimento's avatar
      js: Root gjs_object_get_property_const() · 5826de6b
      Philip Chimento authored
      Starting with gjs_object_get_property_const() and working backwards, we
      cause another cascade of GC rooting changes.
      One disadvantage of JS::MutableHandle is that it's not so easy to make an
      optional out parameter for a function. Previously, for example, a
      JSObject** parameter could be NULL to indicate the caller wasn't
      interested in the return value. e.g.,
          if (out_obj != NULL) { do_some_op(); *out_obj = something; }
      Now we have a few options. For those optional parameters that eventually
      get passed as the "constructor" out parameter of gjs_init_class_dynamic(),
      the constructor is going to need to be created anyhow. So there it's best
      to pass an ignored handle in.
      In gjs_context_get_frame_info(), where we can avoid doing some work by
      indicating that we don't need the particular out parameters, we use
      mozilla::Maybe. This has an unwieldy API in mozjs24 but is improved to be
      much more convenient in later releases. (If this were C++17, we could use
      std::optional instead.)
    • Philip Chimento's avatar
      js: Root gjs_string_from_utf8() · c2b5c3d4
      Philip Chimento authored
      Starting with gjs_string_from_utf8(), we convert the JS::Value out-arg to
      JS::MutableHandleValue. Working backwards from there in a huge cascade,
      we change JS::Value * to JS::MutableHandleValue in many functions that
      call gjs_string_from_utf8(), and root the values with JS::RootedValue
      where they are created.
      This is mostly straightforward, though requires replacing a few instances
      of a stack-allocated JS::Value array created with g_newa(), with
      JS::AutoValueVector instead.
      In the course of moving to more RAII classes such as JS::Rooted<T>, we
      can get rid of some more gotos in favour of returns.
  24. 04 Oct, 2016 1 commit
    • Philip Chimento's avatar
      js: Rooted objects in private access functions · 2af44fa8
      Philip Chimento authored
      Starting with the functions defined in jsapi-util.h's
      GJS_DEFINE_PRIV_FROM_JS macro, we convert the JSObject pointers there to
      JS::HandleObjects, in order to be able to pass them to
      JS_GetInstancePrivate() in mozjs31 which will only accept HandleObjects.
      We work backwards from there, in a huge cascade, changing JSObject* to
      JS::HandleObject in all function argument types that call into those
      functions, and rooting the objects with JS::RootedObject where they are
      This is mostly straightforward but object_init_list in object.cpp needed
      some extra attention. Normally objects are rooted for the duration of a
      scope. In this case, we used a GSList to keep track of the objects past
      the end of the scope, so they could be fetched again in the GObject's
      construct() vfunc. With the normal rooting, that does not work because
      the objects can be moved or GC'd after the original scope ends. Instead
      we have to use JS_AddNamedObjectRoot() and JS_RemoveObjectRoot(). This
      can be changed to a nicer API in mozjs31, JS::PersistentRooted.
  25. 28 Sep, 2016 1 commit
    • Philip Chimento's avatar
      js: Discontinue usage of JSBool · e26191a1
      Philip Chimento authored
      In mozjs31, JSBool and its values JS_TRUE and JS_FALSE are discontinued
      in favor of regular C++ bool, true, and false. In order to ease porting
      to mozjs31, we switch to C++ booleans everywhere.
      Almost everywhere, that is. In some cases bool *, or function pointers
      with bool return types, will not automatically be cast. We therefore leave
      a few instances of JSBool in the code. These will be removed when the
      actual port to mozjs31 happens.
      Fixes a few formatting glitches in lines of code that were touched
  26. 22 Sep, 2016 1 commit
  27. 29 Sep, 2014 1 commit
  28. 10 Apr, 2014 1 commit
  29. 23 Feb, 2014 1 commit
  30. 10 Feb, 2014 1 commit
    • Colin Walters's avatar
      Fix assertions during context dispose · be5c12c4
      Colin Walters authored
      The current toggle ref code has and assertion that we don't have a
      DOWN notification pending while the object is supposed to be live -
      and during normal operation, this is true.
      Except at context shutdown, we force the JS object to be destroyed,
      which can cause recursion into a dispose handler of a gobject, which
      can then queue a toggle down.  Then we later force dispose that
      object, and find the DOWN pending.
      Now, we could simply avoid all of this insanity by default and allow
      the kernel to clean up our state much faster, in a more power
      efficient way by simply not doing any of this...
      However, there are valid use cases for wanting "clean" exits, such as
      valgrind.  So this patch fixes things up for the dispose by iterating
      over the entire live object list before we drop into the JS context
      destruction, breaking the JS <-> C association.  This safely clears
      the toggle refs, so the JS side is just JS cleanup, we don't reenter
      GObject land.
      This will make several of the OSTree tests written using gjs start
      passing in Continuous again.  \o/
  31. 25 Oct, 2013 1 commit
  32. 13 May, 2013 1 commit
  33. 08 Apr, 2013 1 commit