1/*
2 * Copyright (c) 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1.  Redistributions of source code must retain the above copyright
11 *     notice, this list of conditions and the following disclaimer.
12 * 2.  Redistributions in binary form must reproduce the above copyright
13 *     notice, this list of conditions and the following disclaimer in the
14 *     documentation and/or other materials provided with the distribution.
15 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of its
16 *     contributors may be used to endorse or promote products derived from
17 *     this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * Portions of this software have been released under the following terms:
31 *
32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC.
33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY
34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION
35 *
36 * To anyone who acknowledges that this file is provided "AS IS"
37 * without any express or implied warranty:
38 * permission to use, copy, modify, and distribute this file for any
39 * purpose is hereby granted without fee, provided that the above
40 * copyright notices and this notice appears in all source code copies,
41 * and that none of the names of Open Software Foundation, Inc., Hewlett-
42 * Packard Company or Digital Equipment Corporation be used
43 * in advertising or publicity pertaining to distribution of the software
44 * without specific, written prior permission.  Neither Open Software
45 * Foundation, Inc., Hewlett-Packard Company nor Digital
46 * Equipment Corporation makes any representations about the suitability
47 * of this software for any purpose.
48 *
49 * Copyright (c) 2007, Novell, Inc. All rights reserved.
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 *
54 * 1.  Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 * 2.  Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in the
58 *     documentation and/or other materials provided with the distribution.
59 * 3.  Neither the name of Novell Inc. nor the names of its contributors
60 *     may be used to endorse or promote products derived from this
61 *     this software without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 *
74 * @APPLE_LICENSE_HEADER_END@
75 */
76
77/*
78**  NAME:
79**
80**      mtsbacke.c
81**
82**  FACILITY:
83**
84**      Interface Definition Language (IDL) Compiler
85**
86**  ABSTRACT:
87**
88**  Backend control for MTS compiler
89**
90*/
91
92#include <nidl.h>
93#include <ast.h>
94#include <irep.h>       /* Intermediate Representation defs */
95#include <command.h>
96#include <ddbe.h>       /* Data Driven Backend defs */
97#include <mtsbacke.h>
98#include <hdgen.h>
99#include <cstubmts.h>
100#include <sstubmts.h>
101
102/*
103 * Global type instances and boolean
104 */
105boolean *BE_cmd_opt;
106void    **BE_cmd_val;
107AST_type_n_t *BE_ulong_int_p, *BE_ushort_int_p, *BE_pointer_p, *BE_function_p;
108AST_type_n_t *BE_short_null_p, *BE_long_null_p, *BE_hyper_null_p;
109boolean BE_space_opt, BE_bug_array_align, BE_bug_array_align2,
110        BE_bug_boolean_def
111                                                                ;
112
113#ifdef DUMPERS
114boolean BE_dump_debug, BE_dump_flat, BE_dump_mnode, BE_dump_mool,
115        BE_dump_recs, BE_dump_sends, BE_dump_unode, BE_dump_uool,
116        BE_zero_mem;
117#endif
118
119/*
120 *  be_init
121 *
122 * Initialize the various backend globals
123 */
124static void be_init
125(
126    boolean *cmd_opt,
127    void **cmd_val
128)
129{
130    boolean *bugs;
131
132    /*
133     * initialize various options-related globals
134     */
135    BE_cmd_opt = cmd_opt;
136    BE_cmd_val = cmd_val;
137    BE_space_opt = cmd_opt[opt_space_opt];
138#ifdef DUMPERS
139    BE_dump_debug = cmd_opt[opt_dump_debug];
140    BE_dump_flat  = cmd_opt[opt_dump_flat];
141    BE_dump_mnode = cmd_opt[opt_dump_mnode];
142    BE_dump_mool  = cmd_opt[opt_dump_mool];
143    BE_dump_recs  = cmd_opt[opt_dump_recs];
144    BE_dump_sends = cmd_opt[opt_dump_sends];
145    BE_dump_unode = cmd_opt[opt_dump_unode];
146    BE_dump_uool  = cmd_opt[opt_dump_uool];
147    BE_zero_mem   = (getenv("IDL_zero_mem") != NULL);
148#endif
149
150    /*
151     *  Backwards compatibility marshalling
152     */
153    bugs = (boolean *)cmd_val[opt_do_bug];
154    BE_bug_array_align = bugs[bug_array_align];
155    BE_bug_array_align2 = bugs[bug_array_align2];
156    BE_bug_boolean_def = bugs[bug_boolean_def];
157
158    /*
159     * initialize global type instances
160     */
161    BE_ulong_int_p = BE_get_type_node (AST_long_unsigned_k);
162    BE_ulong_int_p->alignment_size = 4;
163    BE_ulong_int_p->ndr_size = 4;
164
165    BE_ushort_int_p = BE_get_type_node (AST_short_unsigned_k);
166    BE_ushort_int_p->alignment_size = 2;
167    BE_ushort_int_p->ndr_size = 2;
168
169    BE_pointer_p = BE_get_type_node (AST_pointer_k);
170    BE_pointer_p->alignment_size = 4;
171    BE_pointer_p->ndr_size = 4;
172
173    BE_function_p = BE_get_type_node (AST_function_k);
174    BE_function_p->alignment_size = 0;
175    BE_function_p->ndr_size = 0;
176
177    BE_short_null_p = BE_get_type_node (AST_null_k);
178    BE_short_null_p->alignment_size = 2;
179    BE_short_null_p->ndr_size = 0;
180
181    BE_long_null_p = BE_get_type_node (AST_null_k);
182    BE_long_null_p->alignment_size = 4;
183    BE_long_null_p->ndr_size = 0;
184
185    BE_hyper_null_p = BE_get_type_node (AST_null_k);
186    BE_hyper_null_p->alignment_size = 8;
187    BE_hyper_null_p->ndr_size = 0;
188
189}
190
191/******************************************************************************/
192/* BE Temporary-Memory Management                                             */
193/******************************************************************************/
194/* ABSTRACT:                                                                  */
195/*   Special BE memory management routines.  The following three routines     */
196/*   provides memory management in contexts (heap zones).  When entering a    */
197/*   context the BE_push_malloc_ctx routine is called, upon entering a        */
198/*   context all calls to BE_ctx_malloc to allocate memory will be associated */
199/*   with the context.  When the context is exited by calling                 */
200/*   BE_pop_malloc_ctx, all memory allocated with BE_ctx_malloc, is freed.    */
201/*                                                                            */
202/* NOTE:                                                                      */
203/*   Memory allocated via BE_ctx_malloc, cannot be freed other than by        */
204/*   exiting the current malloc context as it adds a header to the memory     */
205/*   in order to keep a list of active allocations.  Calls to free() with     */
206/*   allocations returned from BE_ctx_malloc, will cause heap corruption.     */
207/*                                                                            */
208/* ROUTINES:                                                                  */
209/*   BE_cxt_malloc  -- Same interface as MALLOC, if not within a context      */
210/*                     returns memory directly from malloc()                  */
211/*   BE_push_malloc_ctx -- Start new temporary context                        */
212/*                         is used directly and the memory never freed        */
213/*   BE_push_perm_malloc_ctx -- Start new temporary context in which MALLOC   */
214/*   BE_pop_malloc_ctx -- Free all memory allocated since start of context    */
215/*                                                                            */
216/******************************************************************************/
217
218/*
219 * Type used to add our context header to allocations returned from MALLOC
220 */
221typedef struct malloc_t {
222      struct malloc_t *next;    /* Pointer to next allocation on this chain */
223      void *data;               /* Start of memory returned to caller */
224      } malloc_t;
225
226/*
227 * Type used to maintain a list of allocation contexts.
228 */
229typedef struct malloc_ctx_t {
230      struct malloc_ctx_t *next;    /* Pointer to next context */
231      malloc_t *list;               /* Head of allocation chain for this context. */
232      boolean permanent;            /* If true, this is a permanent context */
233      } malloc_ctx_t;
234
235/*
236 * Current malloc context, initially NULL so normal MALLOC is used
237 */
238static malloc_ctx_t *malloc_ctx = NULL;
239
240/*
241** BE_ctx_malloc: allocate memory in the current context.
242*/
243heap_mem *BE_ctx_malloc
244(
245    size_t size
246)
247{
248      malloc_t *new;
249
250      /* If no malloc context, just return memory */
251      if (malloc_ctx == NULL)
252	  return MALLOC (size);
253
254      /* If current malloc context is permanent, then just return memory */
255      if (malloc_ctx->permanent == true)
256	  return MALLOC (size);
257
258      /* Allocate memory with our context header */
259      new = MALLOC (size + sizeof(malloc_t));
260
261      /* Link the new allocation on the current context list */
262      new->next = malloc_ctx->list;
263      malloc_ctx->list = new;
264
265#ifdef DUMPERS
266      /* If BE_zero_mem set, initialize allocated memory to help find bugs */
267      if (BE_zero_mem)
268	  memset(&new->data, 0xFF, size);
269#endif
270
271      /* Return the value after our header for use by the caller */
272      return &new->data;
273}
274
275/*
276** BE_push_malloc_ctx: Push a new context in which memory is allocated
277*/
278void BE_push_malloc_ctx
279(
280      void
281)
282{
283      /*
284       * Allocate a malloc context block to hang allocations made in this
285       * context off of.
286       */
287      malloc_ctx_t *new = NEW (malloc_ctx_t);
288
289      /* Link new context on the top of the context stack */
290      new->next = malloc_ctx;
291      new->list = NULL;
292      new->permanent = false;
293      malloc_ctx = new;
294}
295
296/*
297** BE_pop_malloc_ctx: Pop the current context, freeing all memory allocated
298** within this context (unless it was a permanent context).
299*/
300void BE_pop_malloc_ctx
301(
302    void
303)
304{
305      malloc_t *list,*curr;
306      malloc_ctx_t *ctx;
307
308      /* If we are called with an empty stack, then abort */
309      if (malloc_ctx == NULL)
310          error(NIDL_INTERNAL_ERROR,__FILE__,__LINE__);
311
312      /* Loop through the context freeing all memory */
313      list = malloc_ctx->list;
314      while (list != NULL)
315      {
316          curr = list;
317          list = list->next;
318          free(curr);
319      }
320
321      /* Remove context from the stack, and free the context header */
322      ctx = malloc_ctx;
323      malloc_ctx = malloc_ctx->next;
324      free(ctx);
325}
326
327/*
328 *  BE_main
329 */
330boolean BE_main              /* returns true on successful completion */
331(
332    boolean             *cmd_opt,   /* [in] array of cmd option flags */
333    void                **cmd_val,  /* [in] array of cmd option values */
334    FILE                *h_fid,     /* [in] header file handle, or NULL */
335    FILE                *caux_fid ATTRIBUTE_UNUSED,  /* [in] client aux file handle, or NULL */
336    FILE                *saux_fid ATTRIBUTE_UNUSED,  /* [in] server aux file handle, or NULL */
337    FILE                *cstub_fid, /* [in] cstub file handle, or NULL */
338    FILE                *sstub_fid, /* [in] sstub file handle, or NULL */
339    AST_interface_n_t   *int_p      /* [in] ptr to interface node */
340)
341{
342    DDBE_vectors_t      *dd_vip;    /* Data driven BE vector information ptr */
343
344    be_init (cmd_opt, cmd_val);
345
346    /* Generate the intermediate representation if stubs are required. */
347    if (cstub_fid || sstub_fid)	{
348        IR_gen_irep(cmd_opt, cmd_val, int_p);
349	 }
350
351    /* Print accumulated errors and warnings generated by irep, if any. */
352    if (!cmd_opt[opt_confirm])
353        print_errors();
354
355#if DUMPERS && 0
356	 /* XXX: ??? */
357    /* Dump the IREP if requested. */
358    if (cmd_opt[opt_dump_flat])
359        IR_dump_irep(int_p);
360#endif
361
362    /* Call the Data Driven Backend if stubs are required. */
363    if (cstub_fid || sstub_fid)
364        DDBE_main(cmd_opt, cmd_val, int_p, &dd_vip);
365
366    if (h_fid)
367    {
368        BE_gen_c_header(h_fid, int_p,
369            (boolean *)cmd_val[opt_do_bug], cmd_opt);
370    }
371
372    /*
373     * emit client stub file if requested
374     */
375    if (cstub_fid && error_count == 0)
376        DDBE_gen_cstub(cstub_fid, int_p, lang_c_k,
377            (char *)cmd_val[opt_header], cmd_opt, cmd_val, dd_vip);
378
379    /*
380     * emit server stub file if requested
381     */
382    if (sstub_fid && error_count == 0)
383        BE_gen_sstub (sstub_fid, int_p, lang_c_k, (char *)cmd_val[opt_header],
384                         cmd_opt, cmd_val, dd_vip);
385
386    return (error_count == 0);
387}
388
389/*
390 * Output #includes needed at the start of MTS stubs
391 */
392void CSPELL_mts_includes
393(
394    FILE *fid,
395    char header_name[]
396)
397{
398
399    fprintf (fid, USER_INCLUDE_TEMPLATE, header_name);
400
401    fprintf (fid, INCLUDE_TEMPLATE, "idlddefs.h");
402}
403
404/*
405 * BE_get_name
406 *
407 * Returns a character string given a NAMETABLE_id_t
408 */
409char const *BE_get_name
410(
411    NAMETABLE_id_t id
412)
413{
414    char const *retval;
415
416    NAMETABLE_id_to_string(id, &retval);
417    return retval;
418}
419
420/*
421 * BE_get_type_node
422 *
423 * Allocates and returns a type node
424 */
425AST_type_n_t *BE_get_type_node
426(
427    AST_type_k_t kind
428)
429{
430    AST_type_n_t *new_type = (AST_type_n_t *)BE_ctx_malloc(sizeof(AST_type_n_t));
431
432    new_type->fe_info = NULL;
433    new_type->be_info.other = NULL;
434    new_type->name = NAMETABLE_NIL_ID;
435    new_type->defined_as = NULL;
436    new_type->kind = kind;
437    new_type->flags = 0;
438    new_type->xmit_as_type = NULL;
439    new_type->rep_as_type = NULL;
440    new_type->cs_char_type = NULL;
441
442    return new_type;
443}
444
445/******************************************************************************/
446/*                                                                            */
447/*    Dummy - Control of generation of pipe routine declarations              */
448/*                                                                            */
449/******************************************************************************/
450void BE_gen_pipe_routine_decls
451(
452    FILE *fid ATTRIBUTE_UNUSED,
453    AST_interface_n_t *p_interface ATTRIBUTE_UNUSED
454)
455{
456}
457