Skip to content

Commit cef885f

Browse files
committed
Add a way to free any C strings we pass; always do it initially.
1 parent 060905c commit cef885f

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

src/ops/nqp_dyncall.ops

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,10 @@ inline op nqp_native_call_build(out PMC, in PMC, in STR, in STR, in STR, in PMC,
230230
* presumably a type object).
231231
*/
232232
inline op nqp_native_call(out PMC, in PMC, in PMC, in PMC) :base_core {
233-
PMC *args = $4;
234-
PMC *result = PMCNULL;
233+
PMC *args = $4;
234+
PMC *result = PMCNULL;
235+
char **free_strs = NULL;
236+
INTVAL num_strs = 0;
235237
INTVAL i;
236238

237239
/* Get native call body, so we can locate the call info. */
@@ -282,6 +284,9 @@ inline op nqp_native_call(out PMC, in PMC, in PMC, in PMC) :base_core {
282284
body->arg_types[i] == DYNCALL_ARG_UTF16STR ? Parrot_utf16_encoding_ptr :
283285
Parrot_utf8_encoding_ptr);
284286
dcArgPointer(vm, str);
287+
if (!free_strs)
288+
free_strs = mem_sys_allocate(body->num_args * sizeof(char *));
289+
free_strs[num_strs] = str;
285290
}
286291
break;
287292
case DYNCALL_ARG_CSTRUCT:
@@ -291,7 +296,7 @@ inline op nqp_native_call(out PMC, in PMC, in PMC, in PMC) :base_core {
291296
dcArgPointer(vm, NULL);
292297
}
293298
}
294-
299+
295300
/* Call and process return values. */
296301
switch (body->ret_type) {
297302
case DYNCALL_ARG_VOID:
@@ -329,6 +334,13 @@ inline op nqp_native_call(out PMC, in PMC, in PMC, in PMC) :base_core {
329334
result = $2;
330335
}
331336

337+
/* Free any memory that we need to. */
338+
if (free_strs) {
339+
for (i = 0; i < num_strs; i++)
340+
Parrot_str_free_cstring(free_strs[i]);
341+
mem_sys_free(free_strs);
342+
}
343+
332344
/* Finally, free call VM. */
333345
dcFree(vm);
334346

0 commit comments

Comments
 (0)