aboutsummaryrefslogtreecommitdiffstats
path: root/src/vpp-api/java
diff options
context:
space:
mode:
authorMarek Gradzki <mgradzki@cisco.com>2018-06-20 13:15:08 +0200
committerOle Trøan <otroan@employees.org>2018-06-22 07:03:06 +0000
commit02c88e41791b11e8ed5dd08c76fa7bf5991ba3d7 (patch)
treeeacc82d313de92d1c21ec24b92f5b6dcb7937f3c /src/vpp-api/java
parenta7564e8004fd6d9a63eb0605f752f27a71403645 (diff)
jvpp: cleanup JNI generation code (VPP-1153)
Minor cleanup that includes unifying common Java to C and C to Java translation code. Change-Id: I14d63dbe06334c3bbfbde75043de04d2c08f3dfd Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'src/vpp-api/java')
-rwxr-xr-xsrc/vpp-api/java/jvpp/gen/jvppgen/jni_common_gen.py379
-rwxr-xr-xsrc/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py2
-rwxr-xr-xsrc/vpp-api/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py73
3 files changed, 286 insertions, 168 deletions
diff --git a/src/vpp-api/java/jvpp/gen/jvppgen/jni_common_gen.py b/src/vpp-api/java/jvpp/gen/jvppgen/jni_common_gen.py
index 6f2995d4f8c..3b9969c36e0 100755
--- a/src/vpp-api/java/jvpp/gen/jvppgen/jni_common_gen.py
+++ b/src/vpp-api/java/jvpp/gen/jvppgen/jni_common_gen.py
@@ -15,7 +15,7 @@
#
from string import Template
-from jvpp_model import is_array, Class, is_retval
+from jvpp_model import is_array, is_retval, Class
def generate_j2c_identifiers(element, class_ref_name, object_ref_name):
@@ -38,58 +38,71 @@ _REQUEST_FIELD_IDENTIFIER_TEMPLATE = Template("""
""")
-# TODO(VPP-1185): introduce host_to_net functions wrappers and simplify j2c and c2j swap generation
+# TODO(VPP-1187): do not inline JNI object creation inside message handlers to reduce number of special cases
def generate_j2c_swap(element, struct_ref_name):
initialization = []
for field in element.fields:
- field_type = field.type
if is_array(field):
- template = _ARRAY_J2C_NO_SWAP_TEMPLATE
- field_reference_name = field.java_name
- c_name = field.name
- swap_elements = None
- jni_name = None
- if field_type.is_swap_needed:
- template = _ARRAY_J2C_SWAP_TEMPLATE
- host = "%sArrayElements[_i]" % field_reference_name
- net = "%s->%s[_i]" % (struct_ref_name, c_name)
- swap_elements = field_type.get_host_to_net_function(host, net)
- if isinstance(field_type.base_type, Class):
- jni_name = field_type.base_type.jni_name
- host = "%sArrayElement" % field_reference_name
- net = "%s->%s[_i]" % (struct_ref_name, c_name)
- swap_elements = field_type.get_host_to_net_function(host, net)
- template = _CLASS_ARRAY_J2C_TEMPLATE
-
- initialization.append(template.substitute(
- field_reference_name=field_reference_name,
- field_length_check=_generate_field_length_check(field),
- base_type=field_type.base_type.jni_accessor,
- jni_base_type=field_type.base_type.jni_type,
- struct_reference_name=struct_ref_name,
- jni_name=jni_name,
- c_name=c_name,
- swap_elements=swap_elements
- ))
+ initialization.append(_generate_j2c_array_swap(field, struct_ref_name))
else:
- if field_type.is_swap_needed:
- host = field.java_name
- net = "%s->%s" % (struct_ref_name, field.name)
- initialization.append(" %s;" % field_type.get_host_to_net_function(host, net))
- else:
- initialization.append(" %s->%s = %s;" % (struct_ref_name, field.name, field.java_name))
+ initialization.append(_generate_j2c_scalar_swap(field, struct_ref_name))
return "\n".join(initialization)
-_ARRAY_J2C_NO_SWAP_TEMPLATE = Template("""
- if (${field_reference_name}) {
- jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
- ${field_length_check}
- (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}->${c_name});
+
+def _generate_j2c_array_swap(field, struct_ref_name):
+ # TODO(VPP-1186): move the logic to JNI generators
+ base_type = field.type.base_type
+ if isinstance(base_type, Class):
+ return _generate_j2c_object_array_swap(field, struct_ref_name)
+ elif base_type.is_swap_needed:
+ return _generate_j2c_primitive_type_array_swap(field, struct_ref_name)
+ else:
+ return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name)
+
+
+def _generate_j2c_object_array_swap(field, struct_ref_name):
+ field_type = field.type
+ field_reference_name = field.java_name
+ c_name = field.name
+ host = "%sArrayElement" % field_reference_name
+ net = "%s->%s[_i]" % (struct_ref_name, c_name)
+ swap_elements = field_type.get_host_to_net_function(host, net)
+ return _J2C_OBJECT_ARRAY_SWAP_TEMPLATE.substitute(
+ field_reference_name=field_reference_name,
+ field_length_check=_generate_field_length_check(field),
+ swap_elements=swap_elements)
+
+_J2C_OBJECT_ARRAY_SWAP_TEMPLATE = Template("""
+ {
+ if (${field_reference_name}) {
+ size_t _i;
+ jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
+ ${field_length_check}
+ for (_i = 0; _i < cnt; _i++) {
+ jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i);
+ ${swap_elements};
+ }
+ }
}
""")
-_ARRAY_J2C_SWAP_TEMPLATE = Template("""
+
+def _generate_j2c_primitive_type_array_swap(field, struct_ref_name):
+ field_reference_name = field.java_name
+ field_type = field.type
+ host = "%sArrayElements[_i]" % field_reference_name
+ net = "%s->%s[_i]" % (struct_ref_name, field.name)
+ swap_elements = field_type.get_host_to_net_function(host, net)
+ return _J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
+ field_reference_name=field_reference_name,
+ field_length_check=_generate_field_length_check(field),
+ base_type=field_type.base_type.jni_accessor,
+ jni_base_type=field_type.base_type.jni_type,
+ swap_elements=swap_elements
+ )
+
+_J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
if (${field_reference_name}) {
${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
size_t _i;
@@ -102,17 +115,23 @@ _ARRAY_J2C_SWAP_TEMPLATE = Template("""
}
""")
-_CLASS_ARRAY_J2C_TEMPLATE = Template("""
- {
- if (${field_reference_name}) {
- size_t _i;
- jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
- ${field_length_check}
- for (_i = 0; _i < cnt; _i++) {
- jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i);
- ${swap_elements};
- }
- }
+
+def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name):
+ field_type = field.type
+ return _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE.substitute(
+ field_reference_name=field.java_name,
+ field_length_check=_generate_field_length_check(field),
+ base_type=field_type.base_type.jni_accessor,
+ jni_base_type=field_type.base_type.jni_type,
+ struct_reference_name=struct_ref_name,
+ c_name=field.name
+ )
+
+_J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
+ if (${field_reference_name}) {
+ jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
+ ${field_length_check}
+ (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}->${c_name});
}
""")
@@ -135,128 +154,131 @@ _FIELD_LENGTH_CHECK = Template("""
if (cnt > max_size) cnt = max_size;""")
+def _generate_j2c_scalar_swap(field, struct_ref_name):
+ field_type = field.type
+ if field_type.is_swap_needed:
+ host = field.java_name
+ net = "%s->%s" % (struct_ref_name, field.name)
+ return " %s;" % field_type.get_host_to_net_function(host, net)
+ else:
+ return " %s->%s = %s;" % (struct_ref_name, field.name, field.java_name)
+
+
def generate_c2j_swap(element, object_ref_name, struct_ref_name):
msg_java_name = element.java_name_lower
- setters = []
+ initialization = []
for field in element.fields:
- field_type = field.type
if is_retval(field):
# For retval don't generate setters and generate retval check
continue
elif is_array(field):
- jni_name = ""
- template = _ARRAY_C2J_SWAP_TEMPLATE if field_type.is_swap_needed else _ARRAY_C2J_NO_SWAP_TEMPLATE
- if isinstance(field_type.base_type, Class):
- template = _ARRAY_C2J_CLASS_SWAP_TEMPLATE
- jni_name = field_type.base_type.jni_name
- setters.append(template.substitute(
- field_reference_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_type=field_type.jni_type,
- jni_name=jni_name,
- base_type=field_type.base_type.jni_accessor,
- field_length=_generate_array_length(field, struct_ref_name),
- jni_base_type=field_type.base_type.jni_type,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- c_name=field.name
- ))
+ initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name))
else:
- if field_type.is_swap_needed:
- template = _SIMPLE_TYPE_FIELD_SETTER_TEMPLATE
- jni_name = ""
- if isinstance(field_type, Class):
- template = _STRUCT_SETTER_TEMPLATE
- jni_name = field_type.jni_name
- setters.append(template.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_name=jni_name,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- net_to_host_function=field_type.net_to_host_function,
- c_name=field.name
- ))
- else:
- setters.append(_SIMPLE_TYPE_NO_SWAP_FIELD_SETTER_TEMPLATE.substitute(
- java_name=field.java_name,
- class_ref_name=msg_java_name,
- jni_signature=field_type.jni_signature,
- jni_accessor=field_type.jni_accessor,
- object_ref_name=object_ref_name,
- struct_ref_name=struct_ref_name,
- c_name=field.name
- ))
- return "".join(setters)
-
-
-_SIMPLE_TYPE_FIELD_SETTER_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(${struct_ref_name}->${c_name}));
-""")
+ initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name))
+ return "".join(initialization)
-_STRUCT_SETTER_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
- jmethodID ${java_name}Constructor = (*env)->GetMethodID(env, ${java_name}Class, "<init>", "()V");
- jobject ${java_name} = (*env)->NewObject(env, ${java_name}Class, ${java_name}Constructor);
- ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}), ${java_name});
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
- (*env)->DeleteLocalRef(env, ${java_name});
-""")
-_SIMPLE_TYPE_NO_SWAP_FIELD_SETTER_TEMPLATE = Template("""
- jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
- (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${struct_ref_name}->${c_name});
-""")
+def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ # TODO(VPP-1186): move the logic to JNI generators
+ base_type = field.type.base_type
+ if isinstance(base_type, Class):
+ return _generate_c2j_class_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ elif base_type.is_swap_needed:
+ return _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ else:
+ return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
-_ARRAY_C2J_NO_SWAP_TEMPLATE = Template("""
- jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
- ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
- (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}->${c_name});
- (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
- (*env)->DeleteLocalRef(env, ${field_reference_name});
-""")
-_ARRAY_C2J_SWAP_TEMPLATE = Template("""
+def _generate_c2j_class_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_CLASS_ARRAY_SWAP_TEMPLATE.substitute(
+ field_reference_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_name=field_type.base_type.jni_name,
+ field_length=_generate_array_length(field, struct_ref_name),
+ net_to_host_function=field_type.net_to_host_function,
+ struct_ref_name=struct_ref_name,
+ object_ref_name=object_ref_name,
+ c_name=field.name
+ )
+
+_C2J_CLASS_ARRAY_SWAP_TEMPLATE = Template("""
jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
{
- ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
- ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
+ jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
+ jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
+ jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
unsigned int _i;
for (_i = 0; _i < ${field_length}; _i++) {
- ${field_reference_name}ArrayElements[_i] = ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]);
+ jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor);
+ ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}[_i]), ${field_reference_name}ArrayElement);
+ (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
+ (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
}
-
- (*env)->Release${base_type}ArrayElements(env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
(*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
(*env)->DeleteLocalRef(env, ${field_reference_name});
}
""")
-_ARRAY_C2J_CLASS_SWAP_TEMPLATE = Template("""
+
+def _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
+ field_reference_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_type=field_type.jni_type,
+ base_type=field_type.base_type.jni_accessor,
+ field_length=_generate_array_length(field, struct_ref_name),
+ jni_base_type=field_type.base_type.jni_type,
+ object_ref_name=object_ref_name,
+ struct_ref_name=struct_ref_name,
+ net_to_host_function=field_type.net_to_host_function,
+ c_name=field.name
+ )
+
+_C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
{
- jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
- jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
- jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
+ ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
+ ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
unsigned int _i;
for (_i = 0; _i < ${field_length}; _i++) {
- jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class, ${field_reference_name}Constructor);
- ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}[_i]), ${field_reference_name}ArrayElement);
- (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
- (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
+ ${field_reference_name}ArrayElements[_i] = ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]);
}
+
+ (*env)->Release${base_type}ArrayElements(env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
(*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
(*env)->DeleteLocalRef(env, ${field_reference_name});
}
""")
+def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE.substitute(
+ field_reference_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_type=field_type.jni_type,
+ base_type=field_type.base_type.jni_accessor,
+ field_length=_generate_array_length(field, struct_ref_name),
+ jni_base_type=field_type.base_type.jni_type,
+ object_ref_name=object_ref_name,
+ struct_ref_name=struct_ref_name,
+ c_name=field.name
+ )
+
+_C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
+ jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
+ ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
+ (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}->${c_name});
+ (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
+ (*env)->DeleteLocalRef(env, ${field_reference_name});
+""")
+
+
def _generate_array_length(field, struct_ref_name):
if field.array_len_field:
len_field = field.array_len_field
@@ -265,3 +287,76 @@ def _generate_array_length(field, struct_ref_name):
else:
return "%s->%s" % (struct_ref_name, len_field.name)
return field.array_len
+
+
+def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ if field_type.is_swap_needed:
+ # TODO(VPP-1186): move the logic to JNI generators
+ if isinstance(field_type, Class):
+ return _generate_c2j_class_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ else:
+ return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ else:
+ return _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+
+
+def _generate_c2j_class_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_CLASS_SWAP_TEMPLATE.substitute(
+ java_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_name=field_type.jni_name,
+ jni_accessor=field_type.jni_accessor,
+ object_ref_name=object_ref_name,
+ struct_ref_name=struct_ref_name,
+ net_to_host_function=field_type.net_to_host_function,
+ c_name=field.name)
+
+_C2J_CLASS_SWAP_TEMPLATE = Template("""
+ jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
+ jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
+ jmethodID ${java_name}Constructor = (*env)->GetMethodID(env, ${java_name}Class, "<init>", "()V");
+ jobject ${java_name} = (*env)->NewObject(env, ${java_name}Class, ${java_name}Constructor);
+ ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}), ${java_name});
+ (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
+ (*env)->DeleteLocalRef(env, ${java_name});
+""")
+
+
+def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE.substitute(
+ java_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_accessor=field_type.jni_accessor,
+ object_ref_name=object_ref_name,
+ net_to_host_function=field_type.net_to_host_function,
+ struct_ref_name=struct_ref_name,
+ c_name=field.name
+ )
+
+_C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
+ jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
+ (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(${struct_ref_name}->${c_name}));
+""")
+
+
+def _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+ field_type = field.type
+ return _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE.substitute(
+ java_name=field.java_name,
+ class_ref_name=msg_java_name,
+ jni_signature=field_type.jni_signature,
+ jni_accessor=field_type.jni_accessor,
+ object_ref_name=object_ref_name,
+ struct_ref_name=struct_ref_name,
+ c_name=field.name
+ )
+
+_C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE = Template("""
+ jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
+ (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${struct_ref_name}->${c_name});
+""")
diff --git a/src/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py b/src/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py
index a20a90d4720..ad6c2614062 100755
--- a/src/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py
+++ b/src/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py
@@ -31,7 +31,7 @@ def generate_jni(work_dir, model, logger):
json_filename=model.json_api_files,
class_cache=_generate_class_cache(plugin_name, messages),
api_verification=_generate_api_verification(messages),
- type_handlers=generate_type_handlers(model),
+ type_handlers=generate_type_handlers(model, logger),
jni_implementations=generate_jni_impl(model),
msg_handlers=generate_jni_handlers(model),
handler_registration=_generate_handler_registration(messages)))
diff --git a/src/vpp-api/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py b/src/vpp-api/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py
index eb6ab235ba5..c32acc1911c 100755
--- a/src/vpp-api/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py
+++ b/src/vpp-api/java/jvpp/gen/jvppgen/jni_type_handlers_gen.py
@@ -19,39 +19,46 @@ from jni_common_gen import generate_j2c_swap, generate_j2c_identifiers, generate
from jvpp_model import Class
-def generate_type_handlers(model):
+def generate_type_handlers(model, logger):
"""
- Generates msg handlers for all messages except for dumps and requests (handled by vpp, not client).
+ Generates host-to-net and net-to-host functions for all custom types defined in the VPP API
:param model: meta-model of VPP API used for jVPP generation.
+ :param logger: jVPP logger
"""
type_handlers = []
for t in model.types:
- if not isinstance(t, Class):
- continue
- ref_name = t.java_name_lower
- jni_identifiers = generate_j2c_identifiers(t, class_ref_name="%sClass" % ref_name, object_ref_name="_host")
- type_handlers.append(_TYPE_NET_TO_HOST_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- type_reference_name=ref_name,
- class_FQN=t.jni_name,
- jni_identifiers=jni_identifiers,
- type_swap=generate_j2c_swap(t, struct_ref_name="_net")
- ))
-
- type_handlers.append(_TYPE_HOST_TO_NET_TEMPLATE.substitute(
- c_name=t.name,
- json_filename=model.json_api_files,
- json_definition=t.doc,
- type_reference_name=ref_name,
- class_FQN=t.jni_name,
- jni_identifiers=jni_identifiers,
- type_swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net")
- ))
+ #TODO(VPP-1186): move the logic to JNI generators
+ if isinstance(t, Class):
+ _generate_class(model, t, type_handlers)
+ else:
+ logger.debug("Skipping custom JNI type handler generation for %s", t)
return "\n".join(type_handlers)
+
+def _generate_class(model, t, type_handlers):
+ ref_name = t.java_name_lower
+ jni_identifiers = generate_j2c_identifiers(t, class_ref_name="%sClass" % ref_name, object_ref_name="_host")
+ type_handlers.append(_TYPE_NET_TO_HOST_TEMPLATE.substitute(
+ c_name=t.name,
+ json_filename=model.json_api_files,
+ json_definition=t.doc,
+ type_reference_name=ref_name,
+ class_FQN=t.jni_name,
+ jni_identifiers=jni_identifiers,
+ type_swap=generate_j2c_swap(t, struct_ref_name="_net")
+ ))
+
+ type_handlers.append(_TYPE_HOST_TO_NET_TEMPLATE.substitute(
+ c_name=t.name,
+ json_filename=model.json_api_files,
+ json_definition=t.doc,
+ type_reference_name=ref_name,
+ class_FQN=t.jni_name,
+ jni_identifiers=jni_identifiers,
+ type_swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net")
+ ))
+
_TYPE_NET_TO_HOST_TEMPLATE = Template("""
/**
* Host to network byte order conversion for ${c_name} type.
@@ -76,3 +83,19 @@ static inline void _net_to_host_${c_name}(JNIEnv * env, vl_api_${c_name}_t * _ne
jclass ${type_reference_name}Class = (*env)->FindClass(env, "${class_FQN}");
$type_swap
}""")
+
+
+def _generate_scalar_host_to_net_swap(field):
+ field_type = field.type
+ if field_type.is_swap_needed:
+ return field_type.get_host_to_net_function(field.java_name, "*_net")
+ else:
+ return "*_net = %s" % field.java_name
+
+
+def _generate_scalar_net_to_host_swap(field):
+ field_type = field.type
+ if field_type.is_swap_needed:
+ return "%s((%s) _net);" % (field_type.net_to_host_function, field_type.name)
+ else:
+ return "_net" \ No newline at end of file