[seed] Improving arguments prediction logic.
- From: Danilo Cesar Lemes de Paula <danilocesar src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seed] Improving arguments prediction logic.
- Date: Fri, 3 Jun 2016 14:07:50 +0000 (UTC)
commit 4d859dc61590a4d5b3991ceee4b9ff279f1768a4
Author: Danilo Cesar Lemes de Paula <danilo cesar collabora co uk>
Date: Wed May 25 22:24:57 2016 -0300
Improving arguments prediction logic.
Old system works only when the length arguments appears before the
array.
This commit makes it work for both cases (after and before).
libseed/seed-engine.c | 104 ++++++++++++++++++++++++++++++++++++-------------
1 files changed, 77 insertions(+), 27 deletions(-)
---
diff --git a/libseed/seed-engine.c b/libseed/seed-engine.c
index f1a00ba..07cf58c 100644
--- a/libseed/seed-engine.c
+++ b/libseed/seed-engine.c
@@ -443,6 +443,48 @@ seed_gobject_init_method_invoked(JSContextRef ctx,
return JSValueMakeUndefined(ctx);
}
+// Pre-process the arguments list to find which arguments needs to be skipped.
+gint*
+_process_skipped_arguments(const JSValueRef arguments[],
+ GIBaseInfo* info,
+ gint* out_skipped_args)
+{
+ int n_args = g_callable_info_get_n_args((GICallableInfo*) info);
+ int skipped_args = 0;
+ ;
+ int i;
+
+ gint* skip = g_new0(gint, n_args + 1);
+
+ GITypeInfo* type_info = NULL;
+ GIArgInfo* arg_info = NULL;
+
+ for (i = 0; (i < (n_args)); i++) {
+ arg_info = g_callable_info_get_arg((GICallableInfo*) info, i);
+ type_info = g_arg_info_get_type(arg_info);
+ GIDirection dir = g_arg_info_get_direction(arg_info);
+
+ GITypeTag type_tag = g_type_info_get_tag(type_info);
+ gint array_len_pos = g_type_info_get_array_length(type_info);
+
+ if (dir == GI_DIRECTION_IN)
+ if (type_tag == GI_TYPE_TAG_ARRAY
+ && g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_C
+ && array_len_pos >= 0) {
+ skip[array_len_pos] = 1;
+ skipped_args++;
+ }
+
+ g_base_info_unref((GIBaseInfo*) type_info);
+ g_base_info_unref((GIBaseInfo*) arg_info);
+ type_info = NULL;
+ arg_info = NULL;
+ }
+
+ *out_skipped_args = skipped_args;
+ return skip;
+}
+
static JSValueRef
seed_gobject_method_invoked(JSContextRef ctx,
JSObjectRef function,
@@ -459,13 +501,13 @@ seed_gobject_method_invoked(JSContextRef ctx,
GIBaseInfo* iface_info = NULL;
GArgument retval;
GArgument* in_args;
- gint* skipped_args;
GArgument* out_args;
GArgument* out_values;
+ gint* skipped_args = NULL;
gint* out_pos;
gint first_out = -1;
guint use_return_as_out = 0;
- guint n_args, n_in_args, n_out_args, i;
+ guint n_args, n_in_args, n_out_args, i, j;
guint in_args_pos, out_args_pos;
GIArgInfo* arg_info = NULL;
GITypeInfo* type_info = NULL;
@@ -490,20 +532,28 @@ seed_gobject_method_invoked(JSContextRef ctx,
out_pos = g_new0(gint, n_args + 1);
in_args = g_new0(GArgument, n_args + 1);
- skipped_args = g_new0(gint, n_args + 1);
out_args = g_new0(GArgument, n_args + 1);
out_values = g_new0(GArgument, n_args + 1);
n_in_args = n_out_args = 0;
caller_allocated = g_new0(gboolean, n_args + 1);
- memset(skipped_args, 0, n_args);
-
- // start buy pushing the object onto the call stack.
+ // start by pushing the object onto the call stack.
if (instance_method)
in_args[n_in_args++].v_pointer = object;
+ int out_skipped_args = 0;
+ skipped_args
+ = _process_skipped_arguments(arguments, info, &out_skipped_args);
+
// now loop through all the other args.
- for (i = 0; (i < (n_args)); i++) {
+ for (i = 0, j = 0; (i < (n_args)); i++) {
+ if (skipped_args[i]) {
+ SEED_NOTE(INVOCATION, "Skipping parameter %d", i);
+ n_in_args++;
+ j++;
+ continue;
+ }
+
out_pos[i] = -1;
arg_info = g_callable_info_get_arg((GICallableInfo*) info, i);
dir = g_arg_info_get_direction(arg_info);
@@ -542,7 +592,7 @@ seed_gobject_method_invoked(JSContextRef ctx,
g_base_info_get_name((GIBaseInfo*) arg_info), i,
g_base_info_get_name(info), exception);
- if (i + 1 > argumentCount) {
+ if (i + 1 > argumentCount + out_skipped_args) {
if (dir == GI_DIRECTION_OUT) {
GArgument* out_value = &out_values[n_out_args];
@@ -560,14 +610,14 @@ seed_gobject_method_invoked(JSContextRef ctx,
caller_allocated[i] = TRUE;
}
n_out_args++;
- } else if (!skipped_args[i])
+ } else
in_args[n_in_args++].v_pointer = 0;
} else if (dir == GI_DIRECTION_IN || dir == GI_DIRECTION_INOUT) {
if (!g_arg_info_may_be_null(arg_info)) {
gboolean is_null
- = (!arguments[i] || JSValueIsNull(ctx, arguments[i]));
+ = (!arguments[i - j] || JSValueIsNull(ctx, arguments[i - j]));
if (!is_null && (g_type_info_get_tag(type_info)
== GI_TYPE_TAG_INTERFACE)) {
@@ -576,7 +626,8 @@ seed_gobject_method_invoked(JSContextRef ctx,
type_info);
GIInfoType interface_type = g_base_info_get_type(interface);
- gboolean arg_is_object = JSValueIsObject(ctx, arguments[i]);
+ gboolean arg_is_object
+ = JSValueIsObject(ctx, arguments[i - j]);
gboolean is_gvalue
= (interface_type == GI_INFO_TYPE_STRUCT)
@@ -598,7 +649,8 @@ seed_gobject_method_invoked(JSContextRef ctx,
arrays.
*/
if (!is_gvalue && is_struct_or_union && arg_is_object
- && (seed_pointer_get_pointer(ctx, arguments[i]) == 0)) {
+ && (seed_pointer_get_pointer(ctx, arguments[i - j])
+ == 0)) {
is_null = TRUE;
}
g_base_info_unref(interface);
@@ -628,19 +680,18 @@ seed_gobject_method_invoked(JSContextRef ctx,
}
guint out_length = 0;
- if (!skipped_args[i])
- if (!seed_value_to_gi_argument_with_out_length(
- ctx, arguments[i], type_info, transfer,
- &in_args[n_in_args++], &out_length, exception)) {
- seed_make_exception(ctx, exception, "ArgumentError",
- "Unable to make argument %d for"
- " function: %s. \n",
- i + 1, g_base_info_get_name(
- (GIBaseInfo*) info));
-
- retval_ref = JSValueMakeNull(ctx);
- goto invoke_return;
- }
+ if (!seed_value_to_gi_argument_with_out_length(
+ ctx, arguments[i - j], type_info, transfer,
+ &in_args[n_in_args++], &out_length, exception)) {
+ seed_make_exception(ctx, exception, "ArgumentError",
+ "Unable to make argument %d for"
+ " function: %s. \n",
+ i + 1,
+ g_base_info_get_name((GIBaseInfo*) info));
+
+ retval_ref = JSValueMakeNull(ctx);
+ goto invoke_return;
+ }
// check if what we did we did on an array,
// if yes, fill the g_type_info_get_array_length() position with the
@@ -650,8 +701,7 @@ seed_gobject_method_invoked(JSContextRef ctx,
if (type_tag == GI_TYPE_TAG_ARRAY
&& g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_C
&& array_len_pos >= 0) {
- n_in_args++;
- skipped_args[array_len_pos] = 1;
+ skipped_args[array_len_pos] = TRUE;
in_args[array_len_pos + 1].v_uint64 = out_length;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]