/* %Z%%M% %I% %E% */ /* * Copyright (c) 1990, 1991, 1992, 1993, 1995 by Wayne C. Gramlich. * All rights reserved. * * Permission to use, copy, modify, distribute, and sell this software * for any purpose is hereby granted without fee provided that the above * copyright notice and this permission are retained. The author makes * no representations about the suitability of this software for any purpose. * It is provided "as is" without express or implied warranty. */ /* This file contains routine for outputing code for modules: */ #ifndef ERROR_EXPORTS_H #include "error_exports.h" #endif #ifndef FLAGS_DEFS_H #include "flags_defs.h" #endif #ifndef GEN_DEFS_H #include "gen_defs.h" #endif #ifndef GENERATE_EXPORTS_H #include "generate_exports.h" #endif #ifndef LIBC_EXPORTS_H #include "libc_exports.h" #endif #ifndef LINT_H #include "lint.h" #endif #ifndef MODULE_DEFS_H #include "module_defs.h" #endif #ifndef MSG_DEFS_H #include "msg_defs.h" #endif #ifndef OBJECT_DEFS_H #include "object_defs.h" #endif #ifndef ROUTINE_DEFS_H #include "routine_defs.h" #endif #ifndef STR_EXPORTS_H #include "str_exports.h" #endif #ifndef TABLE_EXPORTS_H #include "table_exports.h" #endif #ifndef TYPE_DEFS_H #include "type_defs.h" #endif #ifndef UNIX_ASSERT_H #include "unix_assert.h" #endif #ifndef UNIX_DIRENT_H #include "unix_dirent.h" #endif #ifndef VECTOR_DEFS_H #include "vector_defs.h" #endif /* Lint is a lot happier if we don't #include "run_time_exports.h"! */ extern char *run__time__enums; extern char *run__time__type_defs; extern char *run__time__struct_defs; LOCAL void module_linkage_gen(Module, Gen); /* * module_gen(module, gen) * This routine will generate the C code associated with "module" * using "gen" to control the generated code. */ void module_gen( Module module, Gen gen) { Type_defs import_type_defs; Type_defs type_defs; gen_comments(gen, module->comments, 0); gen_comment(gen, module->comment, 0); if (gen->linkage) { gen_out(gen, "%s", run__time__enums); gen_out(gen, "%s", run__time__type_defs); gen_out(gen, "typedef void *routine__info__type;\n"); gen_out(gen, "%s", run__time__struct_defs); } /* Output the typedefs for the imported types: */ /* Output the type__ref data structure (if necessary): */ if (gen->need_type_ref) { gen_out(gen, "typedef type__ref___struct " "*type__ref___type;\n"); gen_out(gen, "struct type__ref___struct {\n"); gen_out(gen, "%\tchar *name;\n", 1); gen_out(gen, "%\tint size;\n", 1); gen_out(gen, "%\ttype__ref___type *parameters;\n", 1); gen_out(gen, "};\n"); gen_out(gen, "\n"); gen->need_routine_ref = 1; } if (gen->need_routine_ref) { gen_out(gen, "typedef routine__ref___struct " "*routine__ref___type;\n"); gen_out(gen, "struct routine__ref___struct {\n"); gen_out(gen, "%\tvoid *((*routine)(void));\n", 1); gen_out(gen, "%\tvoid *block;\n", 1); gen_out(gen, "\n"); } type_defs = module->type_defs; import_type_defs = module->import_type_defs; type_defs_typedef_gen(type_defs, gen); type_defs_typedef_gen(import_type_defs, gen); gen_out(gen, "\n"); /* Output the typedefs for the multiple types: */ type_refs_multiple_gen(gen->type_tables, gen); type_proto_table_gen(gen->type_tables->type_proto_table, gen); type_defs_enumeration_gen(type_defs, gen); type_defs_enumeration_gen(import_type_defs, gen); type_defs_structure_gen(type_defs, gen); type_defs_structure_gen(import_type_defs, gen); object_table_extern_gen(gen->object_table, gen); routine_table_proto_gen(gen->routine_table, gen); type_defs_external_gen(type_defs, gen); type_defs_external_gen(import_type_defs, gen); /* Output the generic debugger type definitions: */ if (gen->linkage) { if (1 || gen->debug) { gen_out(gen, "extern void " "run__time__assertion_failed(char *, int);\n"); gen_out(gen, "extern void " "run__time__uninitialized__routine(void);\n"); gen_out(gen, "extern void run__time__bad__case(void);\n"); gen_out(gen, "extern void run__time__breakpoint(void);\n"); gen_out(gen, "extern void *run__time__convert__create(int, " "int, char *);\n"); gen_out(gen, "extern void run__time__pop(void);\n"); gen_out(gen, "void run__time__push(activation___object *);\n"); gen_out(gen, "\n"); } gen_out(gen, "extern void run__time__signal(char *);\n"); gen_out(gen, "extern void run__time__routine_print(void *, " "void *);\n"); /* gen_out(gen, "extern void *heap_alloc(heap___type, int);\n"); */ gen_out(gen, "extern module___object %s%s__module__object;\n", gen->flags->package_name, module->name); routine_table_signature_gen(gen->routine_table, gen); } routines_gen(module->routines, gen); objects_gen(module->object_table, gen); type_defs_routines_gen(type_defs, gen); if (gen->linkage) { module_linkage_gen(module, gen); } } /* * module_linkage_gen(module, gen) * This routine will emit all of the module linkage information * for "module" to "gen". */ LOCAL void module_linkage_gen( Module module, Gen gen) { int line_number; Str package_name; int objects_size; Routine routine; Vec(Routine) routines; int routines_size; /* Output the vectors for the module___object structure: */ /*XXX: This code chunk should be migrated to routine.c: */ package_name = gen->flags->package_name; routines = module->routines; routines_size = vec_size(Routine, routines); gen_out(gen, "static routine___object *module___routines[%d] = {\n", routines_size); VEC_LOOP(Routine, routines, routine) { gen_out(gen, "%\t&%s%s__%s__routine__object,\n", 1, package_name, routine->type_ref->name, routine->name); } gen_out(gen, "};\n"); gen_out(gen, "\n"); objects_size = object_table_module_objects_gen(module->object_table, gen); /* Output the module___object structure: */ if (gen->msg->position_split >= 0) { line_number = msg_line_get(gen->msg, gen->msg->position_split); } else { line_number = -1; } gen_out(gen, "module___object %s%s__module__object = {\n", package_name, module->name); gen_out(gen, "%\t%\",\n", 1, package_name); gen_out(gen, "%\t%\",\n", 1, module->name); gen_out(gen, "%\t%\",\n", 1, gen->flags->in_file->full); gen_out(gen, "%\t%\",\n", 1, gen->flags->gen_file->full); gen_out(gen, "%\t%d,\n", 1, line_number); gen_out(gen, "%\t%d,\n", 1, objects_size); if (objects_size == 0) { gen_out(gen, "%\t(object___object **)0,\n", 1); } else { gen_out(gen, "%\tmodule___objects,\n", 1); } gen_out(gen, "%\t%d,\n", 1, 0); /* Types count */ gen_out(gen, "%\t(type___object **)0, \n", 1); /* types */ gen_out(gen, "%\t%d,\n", 1, routines_size); gen_out(gen, "%\tmodule___routines,\n", 1); /* Routines */ gen_out(gen, "%\t%d,\n", 1, /* Used routine count */ routine_table_used_size(gen->routine_table)); gen_out(gen, "%\t(routine___use **)0,\n", 1); gen_out(gen, "%\t%d,\n", 1, 0 /* Object uses count */); gen_out(gen, "%\t(object___use **)0,\n", 1); gen_out(gen, "%\t%d,\n", 1, 0 /* Initial object uses count */); gen_out(gen, "%\t(type___reference **)0,\n", 1); gen_out(gen, "%\t(void **)0,\n", 1); /* Addresses */ gen_out(gen, "};\n"); gen_out(gen, "\n"); /* Output the module initialization routine: */ gen_out(gen, "void %s__module__initialize(void)\n", module->name); gen_out(gen, "{\n"); type_defs_initialization_gen(module->type_defs, gen); type_defs_initialization_gen(module->import_type_defs, gen); gen_out(gen, "}\n"); gen_out(gen, "\n"); }