From 3236c2c573b83bb1568d5a33ee81494de11d279e Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Tue, 27 Aug 2019 17:43:27 -0400 Subject: [PATCH] C API: never return text structures by value TN: S827-015 --- langkit/templates/c_api/header_c.mako | 13 +++++----- .../templates/c_api/pkg_main_body_ada.mako | 24 +++++++++---------- .../templates/c_api/pkg_main_spec_ada.mako | 12 +++++----- langkit/templates/ocaml_api/module_ocaml.mako | 18 ++++++++------ langkit/templates/python_api/module_py.mako | 15 +++++++----- 5 files changed, 44 insertions(+), 38 deletions(-) diff --git a/langkit/templates/c_api/header_c.mako b/langkit/templates/c_api/header_c.mako index 9076a2b7e..abb2442b0 100644 --- a/langkit/templates/c_api/header_c.mako +++ b/langkit/templates/c_api/header_c.mako @@ -358,8 +358,8 @@ extern ${node_kind_type} ${capi.get_name("node_kind")}(${entity_type} *node); ${c_doc('langkit.kind_name')} -extern ${text_type} -${capi.get_name("kind_name")}(${node_kind_type} kind); +extern void +${capi.get_name("kind_name")}(${node_kind_type} kind, ${text_type} *result); ${c_doc('langkit.node_unit')} extern int @@ -375,8 +375,9 @@ extern int ${capi.get_name("node_is_synthetic")}(${entity_type} *node); ${c_doc('langkit.node_short_image')} -extern ${text_type} -${capi.get_name("node_short_image")}(${entity_type} *node); +extern void +${capi.get_name("node_short_image")}(${entity_type} *node, + ${text_type} *result); ${c_doc('langkit.node_text')} extern void @@ -504,8 +505,8 @@ ${capi.get_name('token_is_equivalent')}(${token_type} *left, ${token_type} *right); ${c_doc('langkit.entity_image')} -extern ${text_type} -${capi.get_name('entity_image')}(${entity_type} ent); +extern void +${capi.get_name('entity_image')}(${entity_type} ent, ${text_type} *result); #ifdef __cplusplus } diff --git a/langkit/templates/c_api/pkg_main_body_ada.mako b/langkit/templates/c_api/pkg_main_body_ada.mako index 1ce02362c..3ce46dc3d 100644 --- a/langkit/templates/c_api/pkg_main_body_ada.mako +++ b/langkit/templates/c_api/pkg_main_body_ada.mako @@ -452,8 +452,8 @@ package body ${ada_lib_name}.Implementation.C is return ${node_kind_type}'First; end; - function ${capi.get_name("kind_name")} - (Kind : ${node_kind_type}) return ${text_type} is + procedure ${capi.get_name('kind_name')} + (Kind : ${node_kind_type}; Result : access ${text_type}) is begin Clear_Last_Exception; @@ -461,13 +461,13 @@ package body ${ada_lib_name}.Implementation.C is K : constant ${T.node_kind} := ${T.node_kind}'Enum_Val (Kind); Name : Text_Access renames Node_Kind_Names (K); begin - return (Chars => Name.all'Address, Length => Name'Length, - Is_Allocated => 0); + Result.all := (Chars => Name.all'Address, + Length => Name'Length, + Is_Allocated => 0); end; exception when Exc : others => Set_Last_Exception (Exc); - return (System.Null_Address, 0, Is_Allocated => 0); end; function ${capi.get_name('node_unit')} @@ -503,19 +503,18 @@ package body ${ada_lib_name}.Implementation.C is return 0; end; - function ${capi.get_name('node_short_image')} - (Node : ${entity_type}_Ptr) return ${text_type} is + procedure ${capi.get_name('node_short_image')} + (Node : ${entity_type}_Ptr; Result : access ${text_type}) is begin Clear_Last_Exception; declare Img : constant Text_Type := Short_Text_Image (Node.Node); begin - return Wrap_Alloc (Img); + Result.all := Wrap_Alloc (Img); end; exception when Exc : others => Set_Last_Exception (Exc); - return (System.Null_Address, 0, 0); end; procedure ${capi.get_name('node_text')} @@ -835,19 +834,18 @@ package body ${ada_lib_name}.Implementation.C is return 0; end; - function ${capi.get_name('entity_image')} - (Ent : ${entity_type}_Ptr) return ${text_type} is + procedure ${capi.get_name('entity_image')} + (Ent : ${entity_type}_Ptr; Result : access ${text_type}) is begin Clear_Last_Exception; declare Img : constant Text_Type := Text_Image (Ent.all); begin - return Wrap_Alloc (Img); + Result.all := Wrap_Alloc (Img); end; exception when Exc : others => Set_Last_Exception (Exc); - return (System.Null_Address, 0, 0); end; ---------------- diff --git a/langkit/templates/c_api/pkg_main_spec_ada.mako b/langkit/templates/c_api/pkg_main_spec_ada.mako index 2cabff926..6c33172d0 100644 --- a/langkit/templates/c_api/pkg_main_spec_ada.mako +++ b/langkit/templates/c_api/pkg_main_spec_ada.mako @@ -393,8 +393,8 @@ private package ${ada_lib_name}.Implementation.C is External_name => "${capi.get_name('node_kind')}"; ${ada_c_doc('langkit.node_kind', 3)} - function ${capi.get_name('kind_name')} (Kind : ${node_kind_type}) - return ${text_type} + procedure ${capi.get_name('kind_name')} + (Kind : ${node_kind_type}; Result : access ${text_type}) with Export => True, Convention => C, External_name => "${capi.get_name('kind_name')}"; @@ -421,8 +421,8 @@ private package ${ada_lib_name}.Implementation.C is External_name => "${capi.get_name('node_is_synthetic')}"; ${ada_c_doc('langkit.node_is_synthetic', 3)} - function ${capi.get_name('node_short_image')} - (Node : ${entity_type}_Ptr) return ${text_type} + procedure ${capi.get_name('node_short_image')} + (Node : ${entity_type}_Ptr; Result : access ${text_type}) with Export => True, Convention => C, External_name => "${capi.get_name('node_short_image')}"; @@ -584,8 +584,8 @@ private package ${ada_lib_name}.Implementation.C is External_name => "${capi.get_name('token_is_equivalent')}"; ${ada_c_doc('langkit.token_is_equivalent', 3)} - function ${capi.get_name('entity_image')} - (Ent : ${entity_type}_Ptr) return ${text_type} + procedure ${capi.get_name('entity_image')} + (Ent : ${entity_type}_Ptr; Result : access ${text_type}) with Export => True, Convention => C, External_name => "${capi.get_name('entity_image')}"; diff --git a/langkit/templates/ocaml_api/module_ocaml.mako b/langkit/templates/ocaml_api/module_ocaml.mako index 4a9357c2f..342ff0b1a 100644 --- a/langkit/templates/ocaml_api/module_ocaml.mako +++ b/langkit/templates/ocaml_api/module_ocaml.mako @@ -536,7 +536,9 @@ module CFunctions = struct (ptr ${ocaml_api.c_type(root_entity)} @-> raisable int) let short_image = foreign ~from:c_lib "${capi.get_name('node_short_image')}" - (ptr ${ocaml_api.c_type(root_entity)} @-> raisable Text.c_type) + (ptr ${ocaml_api.c_type(root_entity)} + @-> ptr Text.c_type + @-> raisable void) let node_sloc_range = foreign ~from:c_lib "${capi.get_name('node_sloc_range')}" @@ -554,7 +556,8 @@ module CFunctions = struct let entity_image = foreign ~from:c_lib "${capi.get_name('entity_image')}" (ptr ${ocaml_api.c_type(root_entity)} - @-> raisable Text.c_type) + @-> ptr Text.c_type + @-> raisable void) let node_is_token_node = foreign ~from:c_lib "${capi.get_name('node_is_token_node')}" @@ -1018,12 +1021,17 @@ let ${ocaml_api.field_name(field)} Token.text_range (token_start node) (token_end node) let short_image node = + let c_result_ptr = allocate_n Text.c_type ~count:1 in CFunctions.short_image (addr (${ocaml_api.unwrap_value('node', root_entity, 'context node')})) + c_result_ptr; + !@ c_result_ptr let entity_image node = + let c_result_ptr = allocate_n Text.c_type ~count:1 in let node_c_value = ${ocaml_api.unwrap_value('node', root_entity, None)} in - CFunctions.entity_image (addr node_c_value) + CFunctions.entity_image (addr node_c_value) c_result_ptr; + !@ c_result_ptr let is_token_node node = let node_c_value = ${ocaml_api.unwrap_value('node', root_entity, None)} in @@ -1046,10 +1054,6 @@ let ${ocaml_api.field_name(field)} (addr node_c_value) sloc_ptr result_ptr; ${ocaml_api.check_for_null('!@ result_ptr', root_entity, '(context node)')} - let entity_image node = - let node_c_value = ${ocaml_api.unwrap_value('node', root_entity, None)} in - CFunctions.entity_image (addr node_c_value) - let children_opt node = let node_c_value = ${ocaml_api.unwrap_value('node', root_entity, None)} in let context = context node in diff --git a/langkit/templates/python_api/module_py.mako b/langkit/templates/python_api/module_py.mako index 7d3ac0c3f..25518f3e3 100644 --- a/langkit/templates/python_api/module_py.mako +++ b/langkit/templates/python_api/module_py.mako @@ -1137,9 +1137,10 @@ class ${root_astnode_name}(object): @property def short_image(self): ${py_doc('langkit.node_short_image', 8)} - node = self._unwrap(self) - text = _node_short_image(ctypes.byref(node)) - return text._wrap() + c_node = self._unwrap(self) + c_result = _text() + _node_short_image(ctypes.byref(c_node), ctypes.byref(c_result)) + return c_result._wrap() def lookup(self, sloc): ${py_doc('langkit.lookup_in_node', 8)} @@ -1343,7 +1344,9 @@ class ${root_astnode_name}(object): @property def entity_repr(self): c_value = self._unwrap(self) - return _entity_image(ctypes.byref(c_value))._wrap() + c_result = _text() + _entity_image(ctypes.byref(c_value), ctypes.byref(c_result)) + return c_result._wrap() @property def tokens(self): @@ -1717,7 +1720,7 @@ _node_is_synthetic = _import_func( ) _node_short_image = _import_func( '${capi.get_name("node_short_image")}', - [ctypes.POINTER(${c_entity})], _text + [ctypes.POINTER(${c_entity}), ctypes.POINTER(_text)], None ) _node_text = _import_func( '${capi.get_name("node_text")}', @@ -1796,7 +1799,7 @@ _token_range_text = _import_func( % if T.entity.exposed: _entity_image = _import_func( "${capi.get_name('entity_image')}", - [ctypes.POINTER(${c_entity})], _text + [ctypes.POINTER(${c_entity}), ctypes.POINTER(_text)], None ) % endif