Commit Graph

29555 Commits

Author SHA1 Message Date
Marco Trevisan (Treviño)
25ae968fc2 girepository: Use expected signed types for iterating
We are using various indexes types, but not always using the correct
sign or size, so let's adapt this to ensure we're consistent with the
values we're comparing with.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
91a3399027 girmodule: Ensure we actually use unsigned for gi_ir_module_fatal line 2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
13791b47f6 gistructinfo: Use proper types for offset lookup
This is a private function so we can just use the expected types.

Also this avoids a signed/unsigned conversion.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
19476db825 girepository: Ensure indexed access on members is not overflowing
Even though we expose member access as size_t, a GI info blob can
typically just access to an a number of values that is never bigger
than uint16_t, as that's how the typelib is defined (cfr. typelib
internal header blob sizes and n_* elements).

So let's avoid this to happen by adding a check.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
acabaa1568 gibaseinfo: Ensure the typelib offset is within the allowed limits
Even though we expose the offset as a size_t value, we actually have
a less space for it, so let's ensure this is the case at runtime.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
157f93d2ee girepository: Use size_t for size-related arguments and return types
We used to use unsigned values, while they should be big enough to old
the data we're handling here, it's cleaner and clearer if we use size_t
as type for such values, as it makes straight forward to understand what
a value should contain. It also makes these values more future proof.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
de8ac339fb gitypeinfo: Use gssize to return the array length index
Use a bigger integer value, even though int is more than enough, but
to make it clearer that we're returning a size-related value.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
a3d29b6437 giarginfo: Use gssize to return the closure and destroy indexes
Use a bigger integer value, even though int is more than enough, but
to make it clearer that we're returning a size-related value.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
bc2e4b3de5 girrepository: Replace usage of gsize with standard size_t
We just do a safe s/gsize/size_t/ replacement here without doing any
changes to places in which different size of size_t and gsize may be
actually different and create troubles.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
c8aecbb834 girepository: Use uint8_t pointers instead of guchar 2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
e3aac4281d girrepository: Remove unneeded static check
The check was added to ensure compatibility with previous versions but
this is not something we care anymore with this API/ABI break.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
5c96b0231a girnode: Use unsigned type for unsigned values
Also use proper sized casting for blob values.
2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
9f33015a25 girrepository: Use standard int sized types instead of g[u]int* 2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
e5353ef0c1 girnode: Assign negative value to signed integer 2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
8891429a5b girepository: Use char instead of glib-specific gchar 2024-01-16 18:40:42 +01:00
Marco Trevisan (Treviño)
eda4bfcf95 girrepository: Use void* instead of gpointer 2024-01-16 18:40:37 +01:00
Philip Withnall
1e0cec289c tests: Avoid calling malloc(0) in gvariant tests
Its behaviour is implementation-defined according to POSIX
(https://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html),
and we’d quite like it to consistently return `NULL` for a zero-size
allocation.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-01-16 16:55:08 +00:00
Marco Trevisan (Treviño)
44e4555765 girepository/cmph-bdz-test: Avoid using unused temporary variable 2024-01-16 17:30:49 +01:00
Marco Trevisan (Treviño)
91fc45ea57 girepository: Replace tabs with spaces in indentation
We don't use tabs anywhere and the mixed setup just makes many editors
to cry. So let's just replace the tabs with 8 spaces.
2024-01-16 17:30:37 +01:00
Philip Withnall
f70b3a91d3 Merge branch 'th/g-pointer-bit-lock-ext' into 'main'
[th/g-pointer-bit-lock-ext] glib: add g_pointer_bit_unlock_and_set() and g_pointer_bit_lock_mask_ptr()

See merge request GNOME/glib!3802
2024-01-16 13:43:54 +00:00
Philip Withnall
9fa33feecf Merge branch 'ewlsh/gir-compiler-source' into 'main'
girepository: Add g-ir-compiler source code

Closes #55

See merge request GNOME/glib!3830
2024-01-16 12:18:32 +00:00
Thomas Haller
a9ed0e2491 gbitlock: factor out bit_lock_contended_class() to avoid duplicated code 2024-01-16 12:50:31 +01:00
Thomas Haller
5e1875dbdc gdataset: factor out common code for find/append of key
The duplication is cumbersome. Factor out common pieces to finding the
data by key and appending a new data.
2024-01-16 12:50:31 +01:00
Thomas Haller
f6b24a0a20 gdataset: use g_pointer_bit_lock_and_get() for g_datalist_lock_and_get() 2024-01-16 12:50:31 +01:00
Thomas Haller
5609370de9 gbitlock: add g_pointer_bit_lock_and_get()
Usually, after g_pointer_bit_lock() we want to read the pointer that we
have. In many cases, when we g_pointer_bit_lock() a pointer, we can
access it afterwards without atomic, as nobody is going to modify the
pointer then.

However, gdataset also supports g_datalist_set_flags(), so the pointer
may change at any time and we must always use atomics to read it. For
that reason, g_datalist_lock_and_get() does an atomic read right after
g_pointer_bit_lock().

g_pointer_bit_lock() can easily access the value that it just set. Add
g_pointer_bit_lock_and_get() which can return the value that gets set
afterwards.

Aside from saving the second atomic-get in certain scenarios, the
returned value is also atomically the one that we just set.
2024-01-16 12:50:31 +01:00
Thomas Haller
abe4b4e7d8 gdataset: add and use helper g_datalist_lock_and_get()
In all cases after taking the lock with g_datalist_lock(), we also
get the pointer. And it hardly makes sense otherwise.

Replace g_datalist_lock() by g_datalist_lock_and_get() which does
both steps in one.
2024-01-16 12:26:46 +01:00
Thomas Haller
eada6be364 gdataset: cleanup g_data_remove_internal()
- only use gnewa0() for up to 400 bytes (arbitrarily chosen as
  something that is probably small enough to cover most small tasks
  while fitting easily on the stack). Otherwise fallback to g_new0().

- don't do intermediate G_DATALIST_SET_POINTER(). Set to NULL
  afterwards with g_datalist_unlock_and_set().

- move the g_free(d) after releasing the lock on datalist.
2024-01-16 12:26:46 +01:00
Thomas Haller
435aa01158 gdataset: update pointers at end of g_datalist_id_replace_data()
- when setting datalist to NULL, do it at the end with
  g_datalist_unlock_and_set() to avoid the additional atomic
  operations.
- when freeing the old "d", do that after releasing the bit
  lock.
2024-01-16 12:25:13 +01:00
Thomas Haller
a426410919 gdataset: use guintptr instead of gsize for pointer mangling
The previous code was in practice correct.

  (((guintptr) ptr) | ((gsize) mask))

works even if gsize is smaller than guintptr. And while the C standard
only guarantees that cast between uintptr_t and void* works, on
reasonable compilers it works to directly cast uintptr_t to GData*.

Still, no need for such uncertainty. Just be clear about the involved
types (use guintptr throughout) and cast first to (gpointer).
2024-01-16 12:16:42 +01:00
Thomas Haller
3f34a49ee9 gdataset: simplify g_dataset_destroy_internal() 2024-01-16 12:16:42 +01:00
Thomas Haller
e931162348 gdataset: inline g_datalist_clear_i() in g_dataset_destroy_internal()
g_datalist_clear_i() had only one caller, altough the code comment made
it sound as if in the past there were more.

A function that has only one caller, and then needs a code comment to
explain the context in which it is called, makes the code more complicated
than necessary.

Especially since the function expects to be called with a global lock
held, and then unlocks and relocks. Spreading such things to another
function (which is only used once) makes code harder to follow.

Inline the function, so that we can see all the (trivial) code at one place.
2024-01-16 12:16:42 +01:00
Thomas Haller
8439b589ec gdataset: use g_datalist_unlock_and_set() in gdataset
This saves an additional atomic set.

Also, changing the pointer before the unlock can awake a blocked thread,
but at this point, the lock is still held (and the thread may need to
sleep again). This can be avoided.
2024-01-16 12:16:42 +01:00
Thomas Haller
c4c76d77cb gbitlock: add g_pointer_bit_unlock_and_set() and g_pointer_bit_lock_mask_ptr()
The existing g_pointer_bit_lock() and g_pointer_bit_unlock() API
requires the user to understand/reimplement how bits of the pointer get
mangled. Add helper functions for that.

The useful thing to do with g_pointer_bit_lock() API is to get/set
pointers while having it locked. For example, to set the pointer a user
can do:

    g_pointer_bit_lock (&lockptr, lock_bit);
    ptr2 = set_bit_pointer_as_if_locked(ptr, lock_bit);
    g_atomic_pointer_set (&lockptr, ptr2);
    g_pointer_bit_unlock (&lockptr, lock_bit);

That has several problems:

- it requires one extra atomic operations (3 instead of 2, in the
  non-contended case).

- the first g_atomic_pointer_set() already wakes blocked threads,
  which find themselves still being locked and needs to go back to
  sleep.

- the user needs to re-implement how bit-locking mangles the pointer so
  that it looks as if it were locked.

- while the user tries to re-implement what glib does to mangle the
  pointer for bitlocking, there is no immediate guarantee that they get
  it right.

Now we can do instead:

  g_pointer_bit_lock(&lockptr, lock_bit);
  g_pointer_bit_unlock_and_set(&lockptr, lock_bit, ptr, 0);

This will also emit a critical if @ptr has the locked bit set.
g_pointer_bit_lock() really only works with pointers that have a certain
alignment, and the lowest bits unset. Otherwise, there is no space to
encode both the locking and all pointer values. The new assertion helps
to catch such bugs.

Also, g_pointer_bit_lock_mask_ptr() is here, so we can do:

  g_pointer_bit_lock(&lockptr, lock_bit);
  /* set a pointer separately, when g_pointer_bit_unlock_and_set() is unsuitable. */
  g_atomic_pointer_set(&lockptr, g_pointer_bit_lock_mask_ptr(ptr, lock_bit, TRUE, 0, NULL));
  ...
  g_pointer_bit_unlock(&lockptr, lock_bit);

and:

  g_pointer_bit_lock(&lockptr, lock_bit);
  /* read the real pointer after getting the lock. */
  ptr = g_pointer_bit_lock_mask_ptr(lockptr, lock_bit, FALSE, 0, NULL));
  ...
  g_pointer_bit_unlock(&lockptr, lock_bit);
2024-01-16 12:16:42 +01:00
Philip Withnall
635f8d43eb gvariant-core: Don’t call posix_memalign() with size==0
While glibc is fine with it (and returns a `NULL` pointer), technically
it’s implementation-defined behaviour according to POSIX, so it’s best
avoided.

See
https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html.

In particular, valgrind will warn about it, which is causing failures of
the gdbus-codegen tests when valgrind is enabled. For example,
https://gitlab.gnome.org/GNOME/glib/-/jobs/3460673 gives
```
==15276== posix_memalign() invalid size value: 0
==15276==    at 0x484B7BC: posix_memalign (vg_replace_malloc.c:2099)
==15276==    by 0x49320B2: g_variant_new_from_bytes (gvariant-core.c:629)
==15276==    by 0x4931853: g_variant_new_from_data (gvariant.c:6226)
==15276==    by 0x4B9A951: g_dbus_gvalue_to_gvariant (gdbusutils.c:708)
==15276==    by 0x41BD15: _foo_igen_bat_skeleton_handle_get_property (gdbus-test-codegen-generated.c:13503)
==15276==    by 0x41BFAF: foo_igen_bat_skeleton_dbus_interface_get_properties (gdbus-test-codegen-generated.c:13582)
…
```

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Helps: #3228
2024-01-16 11:04:44 +00:00
Philip Withnall
571636538b Merge branch 'optional-flags' into 'main'
gobject: define HAVE_OPTIONAL_FLAGS for sizeof(void*) > 8

See merge request GNOME/glib!3813
2024-01-16 09:02:22 +00:00
Philip Withnall
0eecb2b876 Merge branch 'genums-cheri' into 'main'
genums: use g_once_init_enter_pointer for GType initializers

See merge request GNOME/glib!3826
2024-01-16 09:00:55 +00:00
Philip Withnall
68d5a0bef2 Merge branch '3037-log-docs' into 'main'
gmessages: Port all doc comments to gi-docgen

See merge request GNOME/glib!3801
2024-01-16 08:59:32 +00:00
David King
bd56539f73 g-ir-compiler: Fix leaks in write_out_typelib
Found by Coverity.

https://bugzilla.redhat.com/show_bug.cgi?id=1938731
2024-01-15 22:44:41 -08:00
Christoph Reiter
98daf20188 Add a --version option to g-ir-compiler and g-ir-generate. Fixes #55 2024-01-15 22:44:41 -08:00
Ting-Wei Lan
496669495c g-ir-{compiler,generate,inspect}: Call setlocale in main function
It is required to correctly show translated messages on some locales.

https://bugzilla.gnome.org/show_bug.cgi?id=760419
2024-01-15 22:44:41 -08:00
Garrett Regier
380ec88f48 g-ir-compiler: Allow multiple --shared-library
https://bugzilla.gnome.org/show_bug.cgi?id=744535
Signed-off-by: Garrett Regier <garrett.regier@riftio.com>
2024-01-15 22:44:41 -08:00
Ben Boeckel
276bbf8f94 g-ir-compiler: message when arguments are wrong
Otherwise the error is "no input files" which is very confusing.

https://bugzilla.gnome.org/show_bug.cgi?id=753160

Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
2024-01-15 22:44:41 -08:00
Dieter Verfaillie
9c428a6a9e g-ir-compiler: remove references to --code, remove --no-init options
The "--code" option was removed years ago in d5b8d8d523c3bc26aa9fe6c364d3a17d325b55b6
so remove references to it from README and g-ir-compiler(1)

Remove the "--no-init" option from g-ir-compiler and g-ir-compiler(1)
as it was documented to "can only be used if --code is also specified",
so no reason to keep it around.
2024-01-15 22:44:41 -08:00
Colin Walters
3f1cd04b20 Drop calls to g_type_init()
And bump our GLib requirement.
2024-01-15 22:44:41 -08:00
Colin Walters
1820dcacf1 Add Emacs mode lines to C sources 2024-01-15 22:44:41 -08:00
Owen W. Taylor
5fa171ea21 Fix error handling when writing out typelib
Return a non-zero result when opening the output file fails and
don't use g_error() for other failures when writing out the file,
since such errors should not produce a core dump.
2024-01-15 22:44:41 -08:00
Colin Walters
70a1394652 girepository: Consistently prefix internal functions with _
This should better avoid them being exported.  Rename
girepository-parser.la to girepository-internals.la for clarity.
2024-01-15 22:44:41 -08:00
Johan Dahlin
35c46e2e2e [GIRepository] Rename GTypelib to GITypelib
Keep a typedef for backwards compatibility, until
the major bindings has moved over.
2024-01-15 22:44:41 -08:00
Colin Walters
45a04358b6 [gircompiler] Clean up parsing
We never actually include multiple modules in the compiler,
so just nuke that.  Also rather than passing around GIrModule
consistently pass around a GIrTypelibBuild structure which
has various things.

This lets us maintain a stack there which we can walk for
better error messages.

Also, fix up the node lookup in giroffsets.c; previously
it didn't really handle includes correctly.  We really need to
switch to always using Foo.Bar (i.e. GIName) names internally...
2024-01-15 22:44:41 -08:00
Colin Walters
b2df59c315 compiler: Remove --code argument
It can't really work right now because we rely on dumping data at runtime,
which requires the library.  If in the future we support static scanning,
we can reinvestigate embedded typelibs.
2024-01-15 22:44:41 -08:00