jvpp: fix memory allocation for variable lenght messages (VPP-841)
Change-Id: I9a46125e3cf9815c08cf8cca17713ec6e9121eae Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
This commit is contained in:
@ -96,14 +96,16 @@ def is_response_field(field_name):
|
|||||||
|
|
||||||
|
|
||||||
def get_args(t, filter):
|
def get_args(t, filter):
|
||||||
arg_list = []
|
arg_names = []
|
||||||
|
arg_types = []
|
||||||
for i in t:
|
for i in t:
|
||||||
if is_crc(i):
|
if is_crc(i):
|
||||||
continue
|
continue
|
||||||
if not filter(i[1]):
|
if not filter(i[1]):
|
||||||
continue
|
continue
|
||||||
arg_list.append(i[1])
|
arg_types.append(i[0])
|
||||||
return arg_list
|
arg_names.append(i[1])
|
||||||
|
return arg_types, arg_names
|
||||||
|
|
||||||
|
|
||||||
def get_types(t, filter):
|
def get_types(t, filter):
|
||||||
@ -143,16 +145,18 @@ def get_definitions(defs):
|
|||||||
# For replies include all the arguments except message_id
|
# For replies include all the arguments except message_id
|
||||||
if util.is_reply(java_name):
|
if util.is_reply(java_name):
|
||||||
types, lengths, crc = get_types(a[1:], is_response_field)
|
types, lengths, crc = get_types(a[1:], is_response_field)
|
||||||
|
args = get_args(a[1:], is_response_field)
|
||||||
func_name[a[0]] = dict(
|
func_name[a[0]] = dict(
|
||||||
[('name', a[0]), ('java_name', java_name),
|
[('name', a[0]), ('java_name', java_name),
|
||||||
('args', get_args(a[1:], is_response_field)), ('full_args', get_args(a[1:], lambda x: True)),
|
('args', args[1]), ('arg_types', args[0]),
|
||||||
('types', types), ('lengths', lengths), crc])
|
('types', types), ('lengths', lengths), crc])
|
||||||
# For requests skip message_id, client_id and context
|
# For requests skip message_id, client_id and context
|
||||||
else:
|
else:
|
||||||
types, lengths, crc = get_types(a[1:], is_request_field)
|
types, lengths, crc = get_types(a[1:], is_request_field)
|
||||||
|
args = get_args(a[1:], is_request_field)
|
||||||
func_name[a[0]] = dict(
|
func_name[a[0]] = dict(
|
||||||
[('name', a[0]), ('java_name', java_name),
|
[('name', a[0]), ('java_name', java_name),
|
||||||
('args', get_args(a[1:], is_request_field)), ('full_args', get_args(a[1:], lambda x: True)),
|
('args', args[1]), ('arg_types', args[0]),
|
||||||
('types', types), ('lengths', lengths), crc])
|
('types', types), ('lengths', lengths), crc])
|
||||||
|
|
||||||
# Indexed by name
|
# Indexed by name
|
||||||
|
@ -248,16 +248,13 @@ struct_setter_templates = {'u8': u8_struct_setter_template,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def jni_request_binding_for_type(field_type, c_name, field_reference_name, field_name, field_length,
|
def jni_request_identifiers_for_type(field_type, field_reference_name, field_name, object_name="request"):
|
||||||
is_variable_len_array, object_name="request"):
|
|
||||||
"""
|
"""
|
||||||
Generates jni code that initializes C structure that corresponds to a field of java object
|
Generates jni code that defines C variable corresponding to field of java object
|
||||||
(dto or custom type). To be used in request message handlers.
|
(dto or custom type). To be used in request message handlers.
|
||||||
:param field_type: type of the field to be initialized (as defined in vpe.api)
|
:param field_type: type of the field to be initialized (as defined in vpe.api)
|
||||||
:param c_name: name of the message struct member to be initialized
|
|
||||||
:param field_reference_name: name of the field reference in generated code
|
:param field_reference_name: name of the field reference in generated code
|
||||||
:param field_name: name of the field (camelcase)
|
:param field_name: name of the field (camelcase)
|
||||||
:param field_length: integer or name of variable that stores field length
|
|
||||||
:param object_name: name of the object to be initialized
|
:param object_name: name of the object to be initialized
|
||||||
"""
|
"""
|
||||||
# field identifiers
|
# field identifiers
|
||||||
@ -266,7 +263,7 @@ def jni_request_binding_for_type(field_type, c_name, field_reference_name, field
|
|||||||
jni_getter = util.jni_field_accessors[field_type]
|
jni_getter = util.jni_field_accessors[field_type]
|
||||||
|
|
||||||
# field identifier
|
# field identifier
|
||||||
msg_initialization = request_field_identifier_template.substitute(
|
return request_field_identifier_template.substitute(
|
||||||
jni_type=jni_type,
|
jni_type=jni_type,
|
||||||
field_reference_name=field_reference_name,
|
field_reference_name=field_reference_name,
|
||||||
field_name=field_name,
|
field_name=field_name,
|
||||||
@ -274,6 +271,17 @@ def jni_request_binding_for_type(field_type, c_name, field_reference_name, field
|
|||||||
jni_getter=jni_getter,
|
jni_getter=jni_getter,
|
||||||
object_name=object_name)
|
object_name=object_name)
|
||||||
|
|
||||||
|
|
||||||
|
def jni_request_binding_for_type(field_type, c_name, field_reference_name, field_length, is_variable_len_array):
|
||||||
|
"""
|
||||||
|
Generates jni code that initializes C structure that corresponds to a field of java object
|
||||||
|
(dto or custom type). To be used in request message handlers.
|
||||||
|
:param field_type: type of the field to be initialized (as defined in vpe.api)
|
||||||
|
:param c_name: name of the message struct member to be initialized
|
||||||
|
:param field_reference_name: name of the field reference in generated code
|
||||||
|
:param field_length: integer or name of variable that stores field length
|
||||||
|
"""
|
||||||
|
|
||||||
# field setter
|
# field setter
|
||||||
field_length_check = ""
|
field_length_check = ""
|
||||||
|
|
||||||
@ -287,7 +295,7 @@ def jni_request_binding_for_type(field_type, c_name, field_reference_name, field
|
|||||||
|
|
||||||
struct_setter_template = struct_setter_templates[field_type]
|
struct_setter_template = struct_setter_templates[field_type]
|
||||||
|
|
||||||
msg_initialization += struct_setter_template.substitute(
|
msg_initialization = struct_setter_template.substitute(
|
||||||
c_name=c_name,
|
c_name=c_name,
|
||||||
field_reference_name=field_reference_name,
|
field_reference_name=field_reference_name,
|
||||||
field_length_check=field_length_check)
|
field_length_check=field_length_check)
|
||||||
|
@ -113,6 +113,7 @@ request_field_identifier_template = Template("""
|
|||||||
${jni_type} ${field_reference_name} = (*env)->Get${jni_getter}(env, ${object_name}, ${field_reference_name}FieldId);
|
${jni_type} ${field_reference_name} = (*env)->Get${jni_getter}(env, ${object_name}, ${field_reference_name}FieldId);
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
jni_msg_size_template = Template(""" + ${array_length}*sizeof(${element_type})""")
|
||||||
|
|
||||||
jni_impl_template = Template("""
|
jni_impl_template = Template("""
|
||||||
/**
|
/**
|
||||||
@ -127,9 +128,11 @@ JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${java_plugin_name
|
|||||||
u32 my_context_id = vppjni_get_context_id (&jvpp_main);
|
u32 my_context_id = vppjni_get_context_id (&jvpp_main);
|
||||||
$request_class
|
$request_class
|
||||||
|
|
||||||
|
$jni_identifiers
|
||||||
|
|
||||||
// create message:
|
// create message:
|
||||||
mp = vl_msg_api_alloc(sizeof(*mp));
|
mp = vl_msg_api_alloc(${msg_size});
|
||||||
memset (mp, 0, sizeof (*mp));
|
memset (mp, 0, ${msg_size});
|
||||||
mp->_vl_msg_id = ntohs (get_message_id(env, "${c_name}_${crc}"));
|
mp->_vl_msg_id = ntohs (get_message_id(env, "${c_name}_${crc}"));
|
||||||
mp->client_index = plugin_main->my_client_index;
|
mp->client_index = plugin_main->my_client_index;
|
||||||
mp->context = clib_host_to_net_u32 (my_context_id);
|
mp->context = clib_host_to_net_u32 (my_context_id);
|
||||||
@ -155,8 +158,10 @@ def generate_jni_impl(func_list, plugin_name, inputfile):
|
|||||||
|
|
||||||
arguments = ''
|
arguments = ''
|
||||||
request_class = ''
|
request_class = ''
|
||||||
|
jni_identifiers = ''
|
||||||
msg_initialization = ''
|
msg_initialization = ''
|
||||||
f_name_uppercase = f_name.upper()
|
f_name_uppercase = f_name.upper()
|
||||||
|
msg_size = 'sizeof(*mp)'
|
||||||
|
|
||||||
if f['args']:
|
if f['args']:
|
||||||
arguments = ', jobject request'
|
arguments = ', jobject request'
|
||||||
@ -166,13 +171,19 @@ def generate_jni_impl(func_list, plugin_name, inputfile):
|
|||||||
java_name_upper=camel_case_function_name_upper,
|
java_name_upper=camel_case_function_name_upper,
|
||||||
plugin_name=plugin_name)
|
plugin_name=plugin_name)
|
||||||
|
|
||||||
for t in zip(f['types'], f['args'], f['lengths']):
|
for t in zip(f['types'], f['args'], f['lengths'], f['arg_types']):
|
||||||
field_name = util.underscore_to_camelcase(t[1])
|
field_name = util.underscore_to_camelcase(t[1])
|
||||||
|
is_variable_len_array = t[2][1]
|
||||||
|
if is_variable_len_array:
|
||||||
|
msg_size += jni_msg_size_template.substitute(array_length=util.underscore_to_camelcase(t[2][0]),
|
||||||
|
element_type=t[3])
|
||||||
|
jni_identifiers += jni_gen.jni_request_identifiers_for_type(field_type=t[0],
|
||||||
|
field_reference_name=field_name,
|
||||||
|
field_name=field_name)
|
||||||
msg_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=t[1],
|
msg_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=t[1],
|
||||||
field_reference_name=field_name,
|
field_reference_name=field_name,
|
||||||
field_name=field_name,
|
|
||||||
field_length=t[2][0],
|
field_length=t[2][0],
|
||||||
is_variable_len_array=t[2][1])
|
is_variable_len_array=is_variable_len_array)
|
||||||
|
|
||||||
jni_impl.append(jni_impl_template.substitute(
|
jni_impl.append(jni_impl_template.substitute(
|
||||||
inputfile=inputfile,
|
inputfile=inputfile,
|
||||||
@ -185,6 +196,8 @@ def generate_jni_impl(func_list, plugin_name, inputfile):
|
|||||||
plugin_name=plugin_name,
|
plugin_name=plugin_name,
|
||||||
java_plugin_name=plugin_name.title(),
|
java_plugin_name=plugin_name.title(),
|
||||||
request_class=request_class,
|
request_class=request_class,
|
||||||
|
jni_identifiers=jni_identifiers,
|
||||||
|
msg_size=msg_size,
|
||||||
msg_initialization=msg_initialization,
|
msg_initialization=msg_initialization,
|
||||||
args=arguments))
|
args=arguments))
|
||||||
|
|
||||||
|
@ -108,12 +108,14 @@ def generate_struct_initialization(type_def, c_name_prefix, object_name, indent)
|
|||||||
for t in zip(type_def['types'], type_def['args'], type_def['lengths']):
|
for t in zip(type_def['types'], type_def['args'], type_def['lengths']):
|
||||||
field_reference_name = "${c_name}" + util.underscore_to_camelcase_upper(t[1])
|
field_reference_name = "${c_name}" + util.underscore_to_camelcase_upper(t[1])
|
||||||
field_name = util.underscore_to_camelcase(t[1])
|
field_name = util.underscore_to_camelcase(t[1])
|
||||||
|
struct_initialization += jni_gen.jni_request_identifiers_for_type(field_type=t[0],
|
||||||
|
field_reference_name=field_reference_name,
|
||||||
|
field_name=field_name,
|
||||||
|
object_name=object_name)
|
||||||
struct_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=c_name_prefix + t[1],
|
struct_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=c_name_prefix + t[1],
|
||||||
field_reference_name=field_reference_name,
|
field_reference_name=field_reference_name,
|
||||||
field_name=field_name,
|
field_length=t[2][0],
|
||||||
field_length=t[2][0],
|
is_variable_len_array=t[2][1])
|
||||||
is_variable_len_array=t[2][1],
|
|
||||||
object_name=object_name)
|
|
||||||
return indent + struct_initialization.replace('\n', '\n' + indent)
|
return indent + struct_initialization.replace('\n', '\n' + indent)
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user