C API: never return text structures by value

TN: S827-015
This commit is contained in:
Pierre-Marie de Rodat
2019-08-27 17:43:27 -04:00
committed by Raphaël AMIARD
parent 386a5b6cbc
commit 3236c2c573
5 changed files with 44 additions and 38 deletions

View File

@@ -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
}

View File

@@ -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;
----------------

View File

@@ -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')}";

View File

@@ -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

View File

@@ -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