summaryrefslogtreecommitdiff
path: root/gi/arg-cache.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Some really rough work on fixing function pointer supportewlsh/fix-function-pointersEvan Welsh2021-08-061-3/+18
| | | | | Not sure if we should go this route or wrap in a callback, I'd prefer if we can go this route to avoid adding JS wrapping
* GjsCallBackTrampoline: Inherit from Gjs::Closure (and so GClosure)Marco Trevisan (Treviño)2021-08-011-10/+8
| | | | | | | | | | | | | | | | The callback trampoline is in fact a GClosure, but we were just composing one. We can instead just inherit from it now, given that the Gjs::Closure will allocate the needed memory via the closure allocator and handle the references via native closure reference system (avoid to duplicate that). As per this, some less memory used as we save a pointer and the reference counting. The only bit we need to handle is the destruction as we need to be sure to call the proper type destructor on closure finalization. So, adding an utility function that ensures this happens for each type and that we won't call the base destructor twice.
* closure: Reimplement to be a C++ class with custom heap allocatorMarco Trevisan (Treviño)2021-08-011-1/+2
| | | | | | | | | | | | | To create closures we used to create an internal closure structure that for which we were handling construction and destruction manually. C++ allows us to use some nicer features though, and we can take advantage of them once we leave the role of allocating and deallocating the memory to GClosure functions. This can be nicely done overriding the new and delete operators that will give us the size to allocate exactly as the closure creator function expects to receive.
* Value: add Gjs::AutoGValue and use this to handle lifetime of GValuesMarco Trevisan (Treviño)2021-05-181-2/+1
| | | | | | | | | Add a simple structure that wraps GValue that allows us handling lifetime of GValue's in a nicer way and redefine AutoGValueVector with it transparently. In this way the allocated data keeps being structured as GValues but we handle its initializations without errors.
* object: Make ensure_toggle_reference to follow the JS API so we can throwMarco Trevisan (Treviño)2021-05-181-1/+2
|
* gjs: Ensure that we always use unique names for static values and typesMarco Trevisan (Treviño)2021-05-131-1/+3
| | | | This is a prepartory work to get the unity builds possible
* arg-cache: Fix rebase collisionPhilip Chimento2021-05-031-1/+1
| | | | | | This was a more recent change than the branch that was just merged. Unreviewed, pushing to fix build.
* Merge branch '386-arg-cache-not-supported' into 'master'Philip Chimento2021-05-041-102/+88
|\ | | | | | | | | | | | | arg-cache: Never throw when building the argument cache Closes #386 See merge request GNOME/gjs!590
| * arg-cache: Never throw when building the argument cachePhilip Chimento2021-03-201-102/+88
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, the methods for building the argument cache for a function could fail, and throw an exception. Normally this was not a problem, since the argument cache was built when creating the Function object, and that was generally created right before it was about to be called. However, static methods are created eagerly when defining a type's constructor, so if a type contained a method that would throw when building the argument cache, then merely resolving that type would throw. (For example, resolving `GLib.ByteArray` would throw.) Instead, change all the argument cache building methods to be infallible. If an argument is not supported in GJS, then its in-marshaller throws instead. This causes the error to happen when the Function object is called, not when it is created. In order to give good exception messages, we add a "reason" field to the GjsArgumentCache union, used by the new gjs_marshal_not_introspectable_in marshaller, and a display_name() method to GjsFunctionCallState. Closes: #386
* | arg-cache: Do not mark a function returning void* as skip-allMarco Trevisan (Treviño)2021-05-031-1/+2
| | | | | | | | | | | | | | | | | | | | | | While it's true that a void function has no return value, this is not true in the case it's a void pointer. Not doing this, will cause a crash at ffi level because we're passing to it a null return value pointer, while it's expecting to fill it with the returned data. Fixes: #406
* | arg: Dynamically get the gtype from JS object when none is providedMarco Trevisan (Treviño)2021-04-151-0/+9
| | | | | | | | | | | | | | | | | | | | In some cases we're handing interfaces with unsed GType, a case is GTypeInstance. When this happen we should rely on fallback marshaller and try to figure out the actual C container for this type getting the gtype from the JS object. This allows to use g_value_init_from_instance() correctly between the others cases.
* | function: Save original allocated pointersPhilip Chimento2021-04-111-30/+27
|/ | | | | | | cppcheck is not smart enough to determine that when we save an allocated pointer plus an offset, and then free the saved pointer minus that offset, it amounts to the same thing. But, maybe it is clearer anyway to save the original pointers and add the offset in an accessor.
* enum-utils.h: Fix type ambiguity on Visual StudioChun-wei Fan2021-03-111-6/+7
| | | | | | | | | | | | Make the wrapper use the underlying type on Visual Studio builds, so that we can pinpoint on the "right" bitwise operator to use on Visual Studio builds, for the class enumeration(s) we may use. Also, on the same token, define casts for Visual Studio for the wrapped types for use on the '|=' and '&=' operators, as well as the '&' and '|' operators that will be used in value assignments so that the compiler does not get upset when converting between the underlying type and the class enumeration type.
* function: Compute the array length coherently to what we do in cacheMarco Trevisan (Treviño)2021-02-131-2/+2
| | | | | | | | | | | | | | When computing an array length to pass to a function call we bother some JSapi code to get a value (that also may be of an incorrect type) while we already compute this value into the arg-cache depending on the GIArgument type. Since this is the correct way of doing this and avoids lots of unneeded checks, let's just expose the function and reuse it. This is also something that will be quite useful to support BigInt as in such case we may create objects instead of numbers, causing this to fail.
* function: Store more call-state data in GjsFunctionCallStateMarco Trevisan (Treviño)2021-01-301-3/+3
| | | | | | | | Make GjsFunctionCallState a bit smarter by saving the bits there and adding few constexpr methods to verify common conditions. This will make possible also to split the function calls so that we can avoid using some C-isms (goto!)
* CI: Fix bug in IWYU mapping filePhilip Chimento2020-11-301-0/+3
| | | | | | | | | | Oops, we accidentally made the IWYU mapping file invalid, so the IWYU job was not functioning correctly. Move the workaround into the postprocessing script, and fix all the include fixes that have been missed in the meantime while this was broken. New code has also exposed some false positives in IWYU, so add those exceptions to the false positive list.
* gi/arg-cache: Only skip array length parameter onceFlorian Müllner2020-11-181-2/+6
| | | | | | | | | | | | If an array-length parameter precedes the corresponding array parameter, we skip counting the latter instead of the former. As the parameter type isn't relevant for the argument counter, that works fine - provided that the length parameter is only used for a single array. That is usually the case, but there are exceptions (for example Gtk4's gtk_accessible_update_property_value()). Address this by only skipping array arguments if the corresponding length parameter wasn't already marked skip-all previously.
* Merge branch 'gvalue-caller-allocates' into 'master'Philip Chimento2020-10-271-19/+32
|\ | | | | | | | | | | | | gi: Support caller-allocates GValue arguments Closes #74 See merge request GNOME/gjs!496
| * arg-cache: Save unsigned state as argument flag, sharing the bit with FILENAMEMarco Trevisan (Treviño)2020-10-221-5/+10
| | | | | | | | | | There won't be any case in which a string can be unsigned, or when a number is a filename, so we can reuse the same bit safely.
| * arg-cache: Use more flags to store argument flagsMarco Trevisan (Treviño)2020-10-221-9/+10
| |
| * gi: Support caller-allocates GValue argumentsMarco Trevisan (Treviño)2020-10-221-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we were handling a GValue caller-allocates argument we actually were changing a new temporary GArgument copy that we actually didn't end up passing to the function that was changing it. To ensure that this doesn't happen: - When a caller-allocates argument is passed to a function, use the actual GIArgument pointer and not deference it. - Include an argument flag that can be used at conversion time to make clear that we're working on the actual caller allocated argument and not in a gjs copy of it. - When converting a JSValue to GValue, act on the caller allocated (possibly by arg-cache) memory, instead of setting a new GValue. As per this we can enable the `vfunc_caller_allocated_out_parameter` test now. This doesn't seem enough to fix GNOME/gjs#74 testcase though as the gtk introspection doesn't give us enough information about being caller-allocated.
| * arg: Use argument flags for the gjs conversion functionsMarco Trevisan (Treviño)2020-10-221-6/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Make arguments more readable and easier to extend when it comes to pass flags to such functions, instead of rely on hard-to-maintain booleans. Using an enum class that needs some more redefinitions but gives more type safety, as per this adding a enum-utils.h header with some smarter templated definitions for operators that match all the enum class types. We automatically define operators for Enum class (only if strongly typed) types, just include this header and the magic will happen now. Internally using a wrapper struct to wrap the return values so that we can define the bool() operator and so no need to use the !! operator anymore for simple true checks.
* | Revert "arg-cache: Save space by not caching GType"wip/verdre/cache-gtypeJonas Dreßler2020-10-221-12/+13
|/ | | | | | | | | | | | | | As found in https://gitlab.gnome.org/GNOME/gjs/-/issues/361, getting the GType using g_registered_type_info_get_g_type() is very expensive and can make up for a significant part of the overhead when calling into a C function. Since the argument cache seems to be fairly small in a typical gnome-shell session (about 1300 entries), the total increased memory usage of about 10kB seems very reasonable given the benefits of the caching. This reverts commit adfb7dc3ba79b17b0cefa47f5249e9da917217ad.
* arg-cache: Support passing GValue objects, not only generated-gvaluesMarco Trevisan (Treviño)2020-10-141-6/+32
| | | | | | | | | | | | | | | | | | | When we create a GValue using the actual constructor we're holding internally a boxed type, and in such case we don't have to try to convert it to another GValue to pass around, but we should just use it as our argument. However, this can't be computed when parsing the argument, but depends case-by-case, as per this when we've a GValue and this is an object containing an actual GValue, pass it around and remember that we've not to free the returned argument, as that will be handled by the boxed wrapper. This allows to finally use some Gtk functions to get GValue parameters as "in/out" parameters, and the gvalue copy function. Add tests checking that this is the case. Fixes #74
* arg-cache: Use simple boxed marshaller if we're handling a GValue methodMarco Trevisan (Treviño)2020-10-141-1/+3
| | | | | | | If our argument is a GValue and it's marked as the instance parameter, then it means we're calling a g_value_* function, and as per this we should not pass a temporary value but we can just pass the object we've initialized locally.
* arg: Improve debugging of numeric marshal conversionsMarco Trevisan (Treviño)2020-10-121-0/+8
|
* arg-cache: Use only one marshaller for all the numeric typesMarco Trevisan (Treviño)2020-10-121-30/+5
| | | | | | Now that we rely on static compiler checks for type safety and conversions, we can use just one function to handle the conversion of all the numerc types as the compiler will do the job for us.
* arg-cache: Add fundamental marshaller.ewlsh/fix-fundamental-parametersEvan Welsh2020-10-081-2/+76
| | | | | | Addresses regression where fundamental objects cannot be passed into functions. Fixes #353
* Merge branch 'ewlsh/fix-null-pointers' into 'master'Philip Chimento2020-10-061-3/+2
|\ | | | | | | | | Prevent passing null pointers when not nullable. See merge request GNOME/gjs!503
| * Prevent passing null pointers when not nullable.Evan Welsh2020-10-011-3/+2
| | | | | | | | The arg-cache marshaller for null (pointers) doesn't check if the argument is nullable. This is a regression introduced by the arg-cache that can cause segfaults in functions such as GLib.str_hash.
* | maint: Convert all existing license/copyright comments to SPDX formatPhilip Chimento2020-10-041-21/+2
| | | | | | | | | | | | | | | | The SPDX format is machine-readable, which should make it much easier to avoid mistakes with licensing and copyright using automated tools. This commit does not add any implicit information. It converts exactly what was already specified into SPDX format comments.
* | arg-cache: Use gjs_arg_set_from_js_value to set arguments from JSMarco Trevisan (Treviño)2020-10-011-69/+45
|/ | | | | | | | | | | We already have a function to set a GArgument from the JS value, taking care of number conversions and out of bound errors, that is used in arg in the same way, so let's use this function to be consistent, ensuring that we can save each type in a container type big enough and that, in case we go out of bounds we can handle this correctly. Only use a simple function override, so that we can handle the out of bound errors the same way we used to do.
* function: Use c++ features to handle GjsCallbackTrampolineMarco Trevisan (Treviño)2020-09-201-2/+2
| | | | | | | Make the struct a bit smarter, including auto pointers and methods to access to the internal values. Still manage the object creation and reference counting externally.
* arg-cache: Make it clearer how we handle the trampoline referencesMarco Trevisan (Treviño)2020-09-201-14/+14
| | | | | | | | | | | | | In arg-cache we add a new reference to the trampoline that is going to be removed on DestroyNotify callback or(?) when the async calls are cleared. However this is quite unclear as it picks multiple types of function scopes. So put all together adding a ref and using a lambda function to unref, so that we have a more readable and understandable code. This fixes also a potential issue when a function is both async and has a callback destroy, as in such case we'd just add one reference, while we'd remove two.
* function: Define a trampoline autopointer cleanup function and use itMarco Trevisan (Treviño)2020-09-201-2/+2
|
* arg-cache: Use switch to select the array length argument typeMarco Trevisan (Treviño)2020-09-191-17/+20
|
* Merge branch 'remove-gslice' into 'master'Philip Chimento2020-09-101-6/+7
|\ | | | | | | | | cleanup: Don't use GSlice anywhere See merge request GNOME/gjs!488
| * cleanup: Don't use GSlice anywhereMarco Trevisan (Treviño)2020-09-041-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | GSlice API is going to be deprecated [1] and marked as such for some years now, even if this change didn't happen yet, there's no point to keep GSlice usage in gjs, considering that we can semplificate it with calls to system allocator using g_new/g_malloc and g_free. Once I applied this change, I've noticed that the memory sanitzer found some leaks in the trampoline code that for some reason GSlice was hiding and that this commit underlines. [1] https://gitlab.gnome.org/GNOME/glib/-/issues/1079
* | arg-cache: Throw an error when handling unsupported caller-allocates typesMarco Trevisan (Treviño)2020-09-101-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Previous of commit aa28329b7 we were assuming that all the caller-allocates function were using an interface tag, that was wrong but at the same time we don't yet support any other type of caller-allocats function yet [1], so if we detect one type that we don't support we should just throw with some valuable error as we used to do and not just crash. Otherwise it would be impossible to test a solution for bug [2]. [1] https://gitlab.gnome.org/GNOME/gjs/-/issues/106 [2] https://gitlab.gnome.org/GNOME/gjs/-/issues/344
* | arg-cache: Don't assume an interface type on caller allocatesMarco Trevisan (Treviño)2020-09-011-2/+3
|/ | | | | | | | | | | When we get an out parameter with caller-allocates flag we assume that it's an interface, but this may not be the case like for array out parameters. As per this, verify that the type tag matches the interface even when we've a caller allocates argument. Closes: https://gitlab.gnome.org/GNOME/gjs/-/issues/344
* Merge branch 'wip/smcv/flags-are-still-int-sized' into 'master'Philip Chimento2020-08-221-7/+11
|\ | | | | | | | | | | | | arg-cache: Always use an unsigned int mask for flags Closes #341 See merge request GNOME/gjs!477
| * arg-cache: Always use an unsigned int mask for flagsSimon McVittie2020-08-221-7/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When retrieving flags from the GIArgumentInfo in set_return_ffi_arg_from_giargument(), we use the v_int member of the union (arguably we ought to use the v_uint member for flags, but we don't), so to avoid undefined behaviour from type-punning we need to store flags via that same member. In particular, even if we somehow convince ourselves that a flags type can have values outside the 32-bit range, it would be incorrect to store them in the v_int64 or v_uint64 member, because when we read them back out it'll be via the v_int member. That's formally undefined behaviour, but in practice will access the first 32 bits of the 64-bit integer, which is the same as (real_value & 0xffff'ffff) on little-endian CPUs, but gives a meaningless result on big-endian. Sure enough, after 1f3984c9 the unit tests start failing on s390x, which is 64-bit big-endian. GLib's GFlagsClass.mask and GFlagsValue.value are of type guint (equivalent to unsigned int), so it can't possibly represent flags outside the range of guint as a GType anyway. To be consistent with that (and have reasonable unsigned arithmetic), go via an unsigned integer. The corresponding fix for enum types was done as a side-effect of 8b2927b0 "arg-cache: Save space in enum bounds". Fixes: 1f3984c9 "arg-cache: extend to handle interface types too" Resolves: https://gitlab.gnome.org/GNOME/gjs/-/issues/341 Signed-off-by: Simon McVittie <smcv@debian.org>
* | arg-cache: Fail in case we try to set an unsupported array length typeMarco Trevisan (Treviño)2020-08-211-0/+2
| |
* | arg-cache: Don't set always the array length to an ulong in little endianMarco Trevisan (Treviño)2020-08-211-8/+0
|/ | | | | | | | | | | | | | | | | | | | | | | | | The size value we get may be in some cases a signed integer and in some others an unsigned one. However in case we're using a little endian architecture we always save it as the GIArgument unsigned value, while we read it depending on the type tag. This seems to work properly in all the architectures, but the assumtion is wrong in armhf, causing a test failure: it('marshals an array with a 64-bit length parameter', function () { expect(() => GIMarshallingTests.array_in_guint64_len([-1, 0, 1, 2])) .not.toThrow(); }); ERROR:/usr/share/gobject-introspection-1.0/tests/gimarshallingtests.c gi_marshalling_tests_array_in_guint64_len: assertion failed (length == 4): (-498216206332 == 4) At the end the switch check is just an extra operation that will ensure us safety, at a really minimal cost at this point (given we've got the tag anyways). Closes: #342
* arg-cache: Associate callback closure with instance objectPhilip Chimento2020-08-091-1/+14
| | | | | | | I mistakenly left this out during a rebase of the argument cache patches. Closes: #338
* arg-cache.cpp: Fix build on Visual StudioChun-wei Fan2020-08-071-118/+121
| | | | | | | | Unfortunately using designated initializers in C++ is a GCCism, which is not allowed in non-GCC C++17, so go back to the traditional way to set up the structures... See: https://en.cppreference.com/w/cpp/language/aggregate_initialization
* maint: Use C++17 attributesPhilip Chimento2020-08-051-27/+22
| | | | | | | | | | | | | Now that we depend on C++17, we can use these attributes that are part of the language, instead of relying on macros to make them portable. (GJS_USE still needs to be defined for public header files, which may be compiled in C.) Attributes which are new in C++17 are [[maybe_unused]], [[nodiscard]], and [[fallthrough]]. [skip cpplint] because cpplint doesn't deal with C++ attributes: https://github.com/google/styleguide/issues/165
* arg-cache: Store marshallers in predefined groupsPhilip Chimento2020-08-011-96/+300
| | | | | | | | | | The four marshaller function pointers cannot be just any functions. There are a relatively small number of configurations of marshallers, so it saves space to write them all out explicitly, and store only one pointer in the argument cache instead of four. It also prevents accidentally leaving a control flow path where one of the marshaller function pointers remains unset.
* arg-cache: Save space by not caching GTypePhilip Chimento2020-08-011-10/+10
| | | | | | | | | | | | The GType is fetchable from the GIRegisteredTypeInfo, and it is the only member keeping the GjsArgumentCache struct from being smaller. However, this is a bit of a tradeoff since g_registered_type_info_get_g_type() involves a call to g_module_symbol(). Hopefully this doesn't have much of an effect on performance, compared to the net benefit of introducing the argument cache in the first place, since g_registered_type_info_get_type() is also used in the "old way" of marshalling values in arg.cpp.
* arg-cache: Save space in enum boundsPhilip Chimento2020-08-011-11/+25
| | | | | | | | | | | | We were storing a 64-bit int for the min and max values of an enum type. However, the documentation of gobject-introspection notes that enum values are always representable in 32 bits, either signed or unsigned, and the use of a 64-bit return type is to easily allow for both. We store the bounds in 32-bit unsigned bitfields, and use a flag that we add to the slop space in GjsArgumentCache (which we can share with number types as well) to indicate whether the bounds should be interpreted as signed or unsigned.