bool gentypes(compile_t* c) { reach_type_t* t; size_t i; genprim_builtins(c); if(c->opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, " Data prototypes\n"); i = HASHMAP_BEGIN; while((t = reach_types_next(&c->reach->types, &i)) != NULL) { if(!make_opaque_struct(c, t)) return false; gendesc_type(c, t); make_debug_info(c, t); make_box_type(c, t); make_dispatch(c, t); gentrace_prototype(c, t); } gendesc_table(c); if(c->opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, " Data types\n"); i = HASHMAP_BEGIN; while((t = reach_types_next(&c->reach->types, &i)) != NULL) { if(!make_struct(c, t)) return false; make_global_instance(c, t); } if(c->opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, " Function prototypes\n"); i = HASHMAP_BEGIN; while((t = reach_types_next(&c->reach->types, &i)) != NULL) { // The ABI size for machine words and tuples is the boxed size. if(t->structure != NULL) t->abi_size = (size_t)LLVMABISizeOfType(c->target_data, t->structure); make_debug_final(c, t); make_pointer_methods(c, t); if(!genfun_method_sigs(c, t)) return false; } if(c->opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, " Functions\n"); i = HASHMAP_BEGIN; while((t = reach_types_next(&c->reach->types, &i)) != NULL) { if(!genfun_method_bodies(c, t)) return false; } if(c->opt->verbosity >= VERBOSITY_INFO) fprintf(stderr, " Descriptors\n"); i = HASHMAP_BEGIN; while((t = reach_types_next(&c->reach->types, &i)) != NULL) { if(!make_trace(c, t)) return false; if(!genserialise(c, t)) return false; gendesc_init(c, t); } return true; }
static bool make_nominal(compile_t* c, ast_t* ast, gentype_t* g, bool prelim) { assert(ast_id(ast) == TK_NOMINAL); ast_t* def = (ast_t*)ast_data(ast); token_id id = ast_id(def); // For traits, just return a raw object pointer. switch(id) { case TK_INTERFACE: case TK_TRAIT: g->underlying = id; g->use_type = c->object_ptr; dwarf_trait(&c->dwarf, g); return true; default: {} } // If we already exist or we're preliminary, we're done. if(setup_name(c, ast, g, prelim)) return true; if(g->primitive == NULL) { // Not a primitive type. Generate all the fields and a trace function. setup_type_fields(g); // Forward declare debug symbols for this nominal, if needed. // At this point, this can only be TK_STRUCT, TK_CLASS, TK_PRIMITIVE, or // TK_ACTOR ast nodes. TK_TYPE has been translated to any of the former // during reification. dwarf_forward(&c->dwarf, g); bool ok = make_struct(c, g); if(!g->done) ok = ok && make_trace(c, g) && make_components(c, g); if(!ok) { free_fields(g); return false; } // Finalise symbols for composite type. if(!g->done) dwarf_composite(&c->dwarf, g); } else { // Emit debug symbols for a basic type (U8, U16, U32...) dwarf_basic(&c->dwarf, g); // Create a box type. make_box_type(c, g); } if(!g->done) { // Generate a dispatch function if necessary. make_dispatch(c, g); // Create a unique global instance if we need one. make_global_instance(c, g); // Generate all the methods. if(!genfun_methods(c, g)) { free_fields(g); return false; } if(g->underlying != TK_STRUCT) gendesc_init(c, g); // Finish off the dispatch function. if(g->underlying == TK_ACTOR) { codegen_startfun(c, g->dispatch_fn, false); codegen_finishfun(c); } // Finish the dwarf frame. dwarf_finish(&c->dwarf); } free_fields(g); g->done = true; return true; }
bool gentypes(compile_t* c) { reachable_type_t* t; size_t i; genprim_builtins(c); PONY_LOG(c->opt, VERBOSITY_INFO, (" Data prototypes\n")); i = HASHMAP_BEGIN; while((t = reachable_types_next(&c->reachable->types, &i)) != NULL) { if(!make_opaque_struct(c, t)) return false; gendesc_type(c, t); make_debug_info(c, t); make_box_type(c, t); make_dispatch(c, t); gentrace_prototype(c, t); } PONY_LOG(c->opt, VERBOSITY_INFO, (" Data types\n")); i = HASHMAP_BEGIN; while((t = reachable_types_next(&c->reachable->types, &i)) != NULL) { if(!make_struct(c, t)) return false; make_global_instance(c, t); } PONY_LOG(c->opt, VERBOSITY_INFO, (" Function prototypes\n")); i = HASHMAP_BEGIN; while((t = reachable_types_next(&c->reachable->types, &i)) != NULL) { make_debug_final(c, t); make_pointer_methods(c, t); if(!genfun_method_sigs(c, t)) return false; } PONY_LOG(c->opt, VERBOSITY_INFO, (" Functions\n")); i = HASHMAP_BEGIN; while((t = reachable_types_next(&c->reachable->types, &i)) != NULL) { if(!genfun_method_bodies(c, t)) return false; } PONY_LOG(c->opt, VERBOSITY_INFO, (" Descriptors\n")); i = HASHMAP_BEGIN; while((t = reachable_types_next(&c->reachable->types, &i)) != NULL) { if(!make_trace(c, t)) return false; gendesc_init(c, t); } return true; }