/* * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Inc. ("Apple") nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Portions of this software have been released under the following terms: * * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION * * To anyone who acknowledges that this file is provided "AS IS" * without any express or implied warranty: * permission to use, copy, modify, and distribute this file for any * purpose is hereby granted without fee, provided that the above * copyright notices and this notice appears in all source code copies, * and that none of the names of Open Software Foundation, Inc., Hewlett- * Packard Company or Digital Equipment Corporation be used * in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Neither Open Software * Foundation, Inc., Hewlett-Packard Company nor Digital * Equipment Corporation makes any representations about the suitability * of this software for any purpose. * * Copyright (c) 2007, Novell, Inc. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Novell Inc. nor the names of its contributors * may be used to endorse or promote products derived from this * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @APPLE_LICENSE_HEADER_END@ */ /* ** NAME: ** ** mtsbacke.c ** ** FACILITY: ** ** Interface Definition Language (IDL) Compiler ** ** ABSTRACT: ** ** Backend control for MTS compiler ** */ #include #include #include /* Intermediate Representation defs */ #include #include /* Data Driven Backend defs */ #include #include #include #include /* * Global type instances and boolean */ boolean *BE_cmd_opt; void **BE_cmd_val; AST_type_n_t *BE_ulong_int_p, *BE_ushort_int_p, *BE_pointer_p, *BE_function_p; AST_type_n_t *BE_short_null_p, *BE_long_null_p, *BE_hyper_null_p; boolean BE_space_opt, BE_bug_array_align, BE_bug_array_align2, BE_bug_boolean_def ; #ifdef DUMPERS boolean BE_dump_debug, BE_dump_flat, BE_dump_mnode, BE_dump_mool, BE_dump_recs, BE_dump_sends, BE_dump_unode, BE_dump_uool, BE_zero_mem; #endif /* * be_init * * Initialize the various backend globals */ static void be_init ( boolean *cmd_opt, void **cmd_val ) { boolean *bugs; /* * initialize various options-related globals */ BE_cmd_opt = cmd_opt; BE_cmd_val = cmd_val; BE_space_opt = cmd_opt[opt_space_opt]; #ifdef DUMPERS BE_dump_debug = cmd_opt[opt_dump_debug]; BE_dump_flat = cmd_opt[opt_dump_flat]; BE_dump_mnode = cmd_opt[opt_dump_mnode]; BE_dump_mool = cmd_opt[opt_dump_mool]; BE_dump_recs = cmd_opt[opt_dump_recs]; BE_dump_sends = cmd_opt[opt_dump_sends]; BE_dump_unode = cmd_opt[opt_dump_unode]; BE_dump_uool = cmd_opt[opt_dump_uool]; BE_zero_mem = (getenv("IDL_zero_mem") != NULL); #endif /* * Backwards compatibility marshalling */ bugs = (boolean *)cmd_val[opt_do_bug]; BE_bug_array_align = bugs[bug_array_align]; BE_bug_array_align2 = bugs[bug_array_align2]; BE_bug_boolean_def = bugs[bug_boolean_def]; /* * initialize global type instances */ BE_ulong_int_p = BE_get_type_node (AST_long_unsigned_k); BE_ulong_int_p->alignment_size = 4; BE_ulong_int_p->ndr_size = 4; BE_ushort_int_p = BE_get_type_node (AST_short_unsigned_k); BE_ushort_int_p->alignment_size = 2; BE_ushort_int_p->ndr_size = 2; BE_pointer_p = BE_get_type_node (AST_pointer_k); BE_pointer_p->alignment_size = 4; BE_pointer_p->ndr_size = 4; BE_function_p = BE_get_type_node (AST_function_k); BE_function_p->alignment_size = 0; BE_function_p->ndr_size = 0; BE_short_null_p = BE_get_type_node (AST_null_k); BE_short_null_p->alignment_size = 2; BE_short_null_p->ndr_size = 0; BE_long_null_p = BE_get_type_node (AST_null_k); BE_long_null_p->alignment_size = 4; BE_long_null_p->ndr_size = 0; BE_hyper_null_p = BE_get_type_node (AST_null_k); BE_hyper_null_p->alignment_size = 8; BE_hyper_null_p->ndr_size = 0; } /******************************************************************************/ /* BE Temporary-Memory Management */ /******************************************************************************/ /* ABSTRACT: */ /* Special BE memory management routines. The following three routines */ /* provides memory management in contexts (heap zones). When entering a */ /* context the BE_push_malloc_ctx routine is called, upon entering a */ /* context all calls to BE_ctx_malloc to allocate memory will be associated */ /* with the context. When the context is exited by calling */ /* BE_pop_malloc_ctx, all memory allocated with BE_ctx_malloc, is freed. */ /* */ /* NOTE: */ /* Memory allocated via BE_ctx_malloc, cannot be freed other than by */ /* exiting the current malloc context as it adds a header to the memory */ /* in order to keep a list of active allocations. Calls to free() with */ /* allocations returned from BE_ctx_malloc, will cause heap corruption. */ /* */ /* ROUTINES: */ /* BE_cxt_malloc -- Same interface as MALLOC, if not within a context */ /* returns memory directly from malloc() */ /* BE_push_malloc_ctx -- Start new temporary context */ /* is used directly and the memory never freed */ /* BE_push_perm_malloc_ctx -- Start new temporary context in which MALLOC */ /* BE_pop_malloc_ctx -- Free all memory allocated since start of context */ /* */ /******************************************************************************/ /* * Type used to add our context header to allocations returned from MALLOC */ typedef struct malloc_t { struct malloc_t *next; /* Pointer to next allocation on this chain */ void *data; /* Start of memory returned to caller */ } malloc_t; /* * Type used to maintain a list of allocation contexts. */ typedef struct malloc_ctx_t { struct malloc_ctx_t *next; /* Pointer to next context */ malloc_t *list; /* Head of allocation chain for this context. */ boolean permanent; /* If true, this is a permanent context */ } malloc_ctx_t; /* * Current malloc context, initially NULL so normal MALLOC is used */ static malloc_ctx_t *malloc_ctx = NULL; /* ** BE_ctx_malloc: allocate memory in the current context. */ heap_mem *BE_ctx_malloc ( size_t size ) { malloc_t *new; /* If no malloc context, just return memory */ if (malloc_ctx == NULL) return MALLOC (size); /* If current malloc context is permanent, then just return memory */ if (malloc_ctx->permanent == true) return MALLOC (size); /* Allocate memory with our context header */ new = MALLOC (size + sizeof(malloc_t)); /* Link the new allocation on the current context list */ new->next = malloc_ctx->list; malloc_ctx->list = new; #ifdef DUMPERS /* If BE_zero_mem set, initialize allocated memory to help find bugs */ if (BE_zero_mem) memset(&new->data, 0xFF, size); #endif /* Return the value after our header for use by the caller */ return &new->data; } /* ** BE_push_malloc_ctx: Push a new context in which memory is allocated */ void BE_push_malloc_ctx ( void ) { /* * Allocate a malloc context block to hang allocations made in this * context off of. */ malloc_ctx_t *new = NEW (malloc_ctx_t); /* Link new context on the top of the context stack */ new->next = malloc_ctx; new->list = NULL; new->permanent = false; malloc_ctx = new; } /* ** BE_pop_malloc_ctx: Pop the current context, freeing all memory allocated ** within this context (unless it was a permanent context). */ void BE_pop_malloc_ctx ( void ) { malloc_t *list,*curr; malloc_ctx_t *ctx; /* If we are called with an empty stack, then abort */ if (malloc_ctx == NULL) error(NIDL_INTERNAL_ERROR,__FILE__,__LINE__); /* Loop through the context freeing all memory */ list = malloc_ctx->list; while (list != NULL) { curr = list; list = list->next; free(curr); } /* Remove context from the stack, and free the context header */ ctx = malloc_ctx; malloc_ctx = malloc_ctx->next; free(ctx); } /* * BE_main */ boolean BE_main /* returns true on successful completion */ ( boolean *cmd_opt, /* [in] array of cmd option flags */ void **cmd_val, /* [in] array of cmd option values */ FILE *h_fid, /* [in] header file handle, or NULL */ FILE *caux_fid ATTRIBUTE_UNUSED, /* [in] client aux file handle, or NULL */ FILE *saux_fid ATTRIBUTE_UNUSED, /* [in] server aux file handle, or NULL */ FILE *cstub_fid, /* [in] cstub file handle, or NULL */ FILE *sstub_fid, /* [in] sstub file handle, or NULL */ AST_interface_n_t *int_p /* [in] ptr to interface node */ ) { DDBE_vectors_t *dd_vip; /* Data driven BE vector information ptr */ be_init (cmd_opt, cmd_val); /* Generate the intermediate representation if stubs are required. */ if (cstub_fid || sstub_fid) { IR_gen_irep(cmd_opt, cmd_val, int_p); } /* Print accumulated errors and warnings generated by irep, if any. */ if (!cmd_opt[opt_confirm]) print_errors(); #if DUMPERS && 0 /* XXX: ??? */ /* Dump the IREP if requested. */ if (cmd_opt[opt_dump_flat]) IR_dump_irep(int_p); #endif /* Call the Data Driven Backend if stubs are required. */ if (cstub_fid || sstub_fid) DDBE_main(cmd_opt, cmd_val, int_p, &dd_vip); if (h_fid) { BE_gen_c_header(h_fid, int_p, (boolean *)cmd_val[opt_do_bug], cmd_opt); } /* * emit client stub file if requested */ if (cstub_fid && error_count == 0) DDBE_gen_cstub(cstub_fid, int_p, lang_c_k, (char *)cmd_val[opt_header], cmd_opt, cmd_val, dd_vip); /* * emit server stub file if requested */ if (sstub_fid && error_count == 0) BE_gen_sstub (sstub_fid, int_p, lang_c_k, (char *)cmd_val[opt_header], cmd_opt, cmd_val, dd_vip); return (error_count == 0); } /* * Output #includes needed at the start of MTS stubs */ void CSPELL_mts_includes ( FILE *fid, char header_name[] ) { fprintf (fid, USER_INCLUDE_TEMPLATE, header_name); fprintf (fid, INCLUDE_TEMPLATE, "idlddefs.h"); } /* * BE_get_name * * Returns a character string given a NAMETABLE_id_t */ char const *BE_get_name ( NAMETABLE_id_t id ) { char const *retval; NAMETABLE_id_to_string(id, &retval); return retval; } /* * BE_get_type_node * * Allocates and returns a type node */ AST_type_n_t *BE_get_type_node ( AST_type_k_t kind ) { AST_type_n_t *new_type = (AST_type_n_t *)BE_ctx_malloc(sizeof(AST_type_n_t)); new_type->fe_info = NULL; new_type->be_info.other = NULL; new_type->name = NAMETABLE_NIL_ID; new_type->defined_as = NULL; new_type->kind = kind; new_type->flags = 0; new_type->xmit_as_type = NULL; new_type->rep_as_type = NULL; new_type->cs_char_type = NULL; return new_type; } /******************************************************************************/ /* */ /* Dummy - Control of generation of pipe routine declarations */ /* */ /******************************************************************************/ void BE_gen_pipe_routine_decls ( FILE *fid ATTRIBUTE_UNUSED, AST_interface_n_t *p_interface ATTRIBUTE_UNUSED ) { }