/*
* Copyright (c) 1995, 1996, 1997, 1998, 1999 The University of Utah and
* the Computer Systems Laboratory at the University of Utah (CSL).
*
* This file is part of Flick, the Flexible IDL Compiler Kit.
*
* Flick is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Flick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flick; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA.
*/
#include <assert.h>
#include <mom/c/libcast.h>
#include <mom/c/pbe.hh>
#include "mach3.h"
/*
* Generate code to free the memory pointed to by a pointer variable or
* parameter, as dictated by the deallocation semantics defined in the passed
* `alloc' structure.
*
* `pexpr' is a C expression evaluating to the pointer whose memory is being
* freed.
*
* `target_type' is the C type of whatever the pointer points to. (The
* pointer's type itself would be a CAST_TYPE_POINTER referring to that type).
*
* `cname' is the name of the PRES_C_INLINE_ALLOCATION_CONTEXT node that is
* associated with this pointer.
*/
void mach3_mu_state::mu_pointer_free(cast_expr pexpr, cast_type target_type,
char *cname)
{
/* We need to find our allocation semantics established by some parent
INLINE_ALLOCATION_CONTEXT node. */
mu_inline_alloc_context *iac = inline_alloc_context;
while (iac) {
if (strcmp(iac->name, cname) == 0)
break;
iac = iac->parent_context;
}
assert(iac);
pres_c_allocation *palloc = iac->alloc;
/* Find the appropriate allocation case, and make sure it's valid. */
pres_c_allocation_u *ualloc = &palloc->cases[current_param_dir];
assert(ualloc->allow != PRES_C_ALLOCATION_INVALID);
pres_c_allocation_case *alloc = &(ualloc->pres_c_allocation_u_u.val);
cast_expr free_expr;
if (!(op & MUST_DEALLOCATE)) /* XXX */
return;
if ((alloc->flags & PRES_C_DEALLOC_EVER) == PRES_C_DEALLOC_NEVER)
return;
/*
* Now we need to find the allocation length:
* If we know the maximum presented length, then use it.
* Otherwise, use the presented length.
*/
cast_expr lexpr;
cast_type ltype;
int gotarg = arglist->getargs(cname, "max_len", &lexpr, <ype);
assert(gotarg);
if (!lexpr)
mu_array_get_pres_length(cname, &lexpr, <ype);
assert(lexpr);
switch (alloc->allocator.kind) {
case PRES_C_ALLOCATOR_OUTOFLINE:
/*
* The deallocation has been taken care of by the
* deallocate flag in the IPC message.
* => Do nothing, not even the default mu_pointer_free().
*/
break;
case PRES_C_ALLOCATOR_NAME:
/*
* For mach_vm frees, we have to pass the size.
* For others, just run the default mu_pointer_free()
*/
if (strcmp(alloc->allocator.pres_c_allocator_u.name,
"mach_vm") == 0) {
/* Call a function to deallocate the storage. */
const char *name = get_deallocator(palloc);
cast_expr size_expr;
if ((lexpr->kind == CAST_EXPR_LIT_PRIM)
&& (lexpr->cast_expr_u_u.lit_prim.u.kind ==
CAST_PRIM_INT)
&& (lexpr->cast_expr_u_u.lit_prim.u.
cast_lit_prim_u_u.i
== 1)
)
/* Special case:
Don't multiply the `sizeof' by 1. */
size_expr = cast_new_expr_sizeof_type(
target_type);
else
/* General case: Multiply by `lexpr'. */
size_expr = cast_new_binary_expr(
CAST_BINARY_MUL,
lexpr,
cast_new_expr_sizeof_type(
target_type));
free_expr = cast_new_expr_call_2(
cast_new_expr_name(name),
pexpr,
size_expr);
cast_stmt free_stmt = cast_new_stmt_expr(free_expr);
/* Now decide when that statement should be invoked. */
if (alloc->flags & PRES_C_DEALLOC_ALWAYS) {
add_stmt(free_stmt);
}
/* Nullify the pointer if requested. */
if (alloc->flags & PRES_C_DEALLOC_NULLIFY)
add_stmt(cast_new_stmt_expr(
cast_new_expr_assign(
pexpr,
cast_new_expr_lit_int(0, 0))
));
break;
}
/* else fall through */
default:
mu_state::mu_pointer_free(pexpr, target_type, cname);
}
}
/* End of file. */
syntax highlighted by Code2HTML, v. 0.9.1