From 02c88e41791b11e8ed5dd08c76fa7bf5991ba3d7 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Wed, 20 Jun 2018 13:15:08 +0200 Subject: [PATCH] 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 --- .../java/jvpp/gen/jvppgen/jni_common_gen.py | 379 +++++++++++++-------- src/vpp-api/java/jvpp/gen/jvppgen/jni_gen.py | 2 +- .../java/jvpp/gen/jvppgen/jni_type_handlers_gen.py | 73 ++-- 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, "", "()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, "", "()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, "", "()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, "", "()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 -- 2.16.6