diff --git a/src/libponyc/codegen/codegen.c b/src/libponyc/codegen/codegen.c index 7686a3cff2..0d668cb55c 100644 --- a/src/libponyc/codegen/codegen.c +++ b/src/libponyc/codegen/codegen.c @@ -977,12 +977,13 @@ LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type, } void codegen_startfun(compile_t* c, LLVMValueRef fun, LLVMMetadataRef file, - LLVMMetadataRef scope, bool bare) + LLVMMetadataRef scope, deferred_reification_t* reify, bool bare) { compile_frame_t* frame = push_frame(c); frame->fun = fun; frame->is_function = true; + frame->reify = reify; frame->bare_function = bare; frame->di_file = file; frame->di_scope = scope; @@ -1006,6 +1007,7 @@ void codegen_pushscope(compile_t* c, ast_t* ast) compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = frame->prev->break_target; frame->break_novalue_target = frame->prev->break_novalue_target; @@ -1111,6 +1113,7 @@ void codegen_pushloop(compile_t* c, LLVMBasicBlockRef continue_target, compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = break_target; frame->break_novalue_target = break_novalue_target; @@ -1130,6 +1133,7 @@ void codegen_pushtry(compile_t* c, LLVMBasicBlockRef invoke_target) compile_frame_t* frame = push_frame(c); frame->fun = frame->prev->fun; + frame->reify = frame->prev->reify; frame->bare_function = frame->prev->bare_function; frame->break_target = frame->prev->break_target; frame->break_novalue_target = frame->prev->break_novalue_target; diff --git a/src/libponyc/codegen/codegen.h b/src/libponyc/codegen/codegen.h index c5ed914301..2b4830b00e 100644 --- a/src/libponyc/codegen/codegen.h +++ b/src/libponyc/codegen/codegen.h @@ -79,6 +79,7 @@ typedef struct compile_frame_t bool is_function; bool early_termination; bool bare_function; + deferred_reification_t* reify; struct compile_frame_t* prev; } compile_frame_t; @@ -240,7 +241,7 @@ LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type, bool pony_abi); void codegen_startfun(compile_t* c, LLVMValueRef fun, LLVMMetadataRef file, - LLVMMetadataRef scope, bool bare); + LLVMMetadataRef scope, deferred_reification_t* reify, bool bare); void codegen_finishfun(compile_t* c); diff --git a/src/libponyc/codegen/gencall.c b/src/libponyc/codegen/gencall.c index 681584711a..ee127285c5 100644 --- a/src/libponyc/codegen/gencall.c +++ b/src/libponyc/codegen/gencall.c @@ -214,17 +214,23 @@ static bool special_case_call(compile_t* c, ast_t* ast, LLVMValueRef* value) return false; AST_GET_CHILDREN(postfix, receiver, method); - ast_t* receiver_type = ast_type(receiver); + ast_t* receiver_type = deferred_reify(c->frame->reify, ast_type(receiver), + c->opt); - if(ast_id(receiver_type) != TK_NOMINAL) - return false; + const char* name = NULL; - AST_GET_CHILDREN(receiver_type, package, id); + if(ast_id(receiver_type) == TK_NOMINAL) + { + AST_GET_CHILDREN(receiver_type, package, id); - if(ast_name(package) != c->str_builtin) - return false; + if(ast_name(package) == c->str_builtin) + name = ast_name(id); + } + + ast_free_unattached(receiver_type); - const char* name = ast_name(id); + if(name == NULL) + return false; if(name == c->str_Bool) return special_case_operator(c, ast, value, true, true); @@ -478,7 +484,7 @@ LLVMValueRef gen_funptr(compile_t* c, ast_t* ast) LLVMValueRef value = gen_expr(c, receiver); // Get the receiver type. - ast_t* type = ast_type(receiver); + ast_t* type = deferred_reify(c->frame->reify, ast_type(receiver), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); @@ -487,6 +493,8 @@ LLVMValueRef gen_funptr(compile_t* c, ast_t* ast) reach_method_t* m = reach_method(t, cap, name, typeargs); LLVMValueRef funptr = dispatch_function(c, t, m, value); + ast_free_unattached(type); + if((m->cap != TK_AT) && (c->linkage != LLVMExternalLinkage)) { // We must reset the function linkage and calling convention since we're @@ -535,13 +543,18 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], size_t args_buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* cast_args = (LLVMValueRef*)ponyint_pool_alloc_size(args_buf_size); + size_t arg_types_buf_size = m->param_count * sizeof(ast_t*); + ast_t** arg_types = (ast_t**)ponyint_pool_alloc_size(arg_types_buf_size); ast_t* arg_ast = ast_child(args_ast); + deferred_reification_t* reify = c->frame->reify; + for(size_t i = 0; i < m->param_count; i++) { + arg_types[i] = deferred_reify(reify, ast_type(arg_ast), c->opt); cast_args[i+1] = gen_assign_cast(c, param_types[i+3], args[i+1], - ast_type(arg_ast)); + arg_types[i]); arg_ast = ast_sibling(arg_ast); } @@ -561,18 +574,15 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], } // Trace while populating the message contents. - arg_ast = ast_child(args_ast); bool need_trace = false; for(size_t i = 0; i < m->param_count; i++) { - if(gentrace_needed(c, ast_type(arg_ast), m->params[i].ast)) + if(gentrace_needed(c, arg_types[i], m->params[i].ast)) { need_trace = true; break; } - - arg_ast = ast_sibling(arg_ast); } LLVMValueRef ctx = codegen_ctx(c); @@ -581,13 +591,11 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], { LLVMValueRef gc = gencall_runtime(c, "pony_gc_send", &ctx, 1, ""); LLVMSetMetadataStr(gc, "pony.msgsend", md); - arg_ast = ast_child(args_ast); for(size_t i = 0; i < m->param_count; i++) { - gentrace(c, ctx, args[i+1], cast_args[i+1], ast_type(arg_ast), + gentrace(c, ctx, args[i+1], cast_args[i+1], arg_types[i], m->params[i].ast); - arg_ast = ast_sibling(arg_ast); } gc = gencall_runtime(c, "pony_send_done", &ctx, 1, ""); @@ -611,6 +619,11 @@ void gen_send_message(compile_t* c, reach_method_t* m, LLVMValueRef args[], ponyint_pool_free_size(params_buf_size, param_types); ponyint_pool_free_size(args_buf_size, cast_args); + + for(size_t i = 0; i < m->param_count; i++) + ast_free_unattached(arg_types[i]); + + ponyint_pool_free_size(arg_types_buf_size, arg_types); } static bool contains_boxable(ast_t* type) @@ -726,6 +739,8 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) AST_GET_CHILDREN(postfix, receiver, method); ast_t* typeargs = NULL; + deferred_reification_t* reify = c->frame->reify; + // Dig through function qualification. switch(ast_id(receiver)) { @@ -735,7 +750,7 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) case TK_FUNREF: case TK_BECHAIN: case TK_FUNCHAIN: - typeargs = method; + typeargs = deferred_reify(reify, method, c->opt); AST_GET_CHILDREN_NO_DECL(receiver, receiver, method); break; @@ -744,12 +759,18 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) // Get the receiver type. const char* method_name = ast_name(method); - ast_t* type = ast_type(receiver); + ast_t* type = deferred_reify(reify, ast_type(receiver), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + token_id cap = cap_dispatch(type); + reach_method_t* m = reach_method(t, cap, method_name, typeargs); + + ast_free_unattached(type); + ast_free_unattached(typeargs); + // Generate the arguments. - size_t count = ast_childcount(positional) + 1; + size_t count = m->param_count + 1; size_t buf_size = count * sizeof(void*); LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); @@ -802,8 +823,6 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) } // Static or virtual dispatch. - token_id cap = cap_dispatch(type); - reach_method_t* m = reach_method(t, cap, method_name, typeargs); LLVMValueRef func = dispatch_function(c, t, m, args[0]); bool is_message = false; @@ -836,9 +855,6 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) { // If we're sending a message, trace and send here instead of calling the // sender to trace the most specific types possible. - token_id cap = cap_dispatch(type); - reach_method_t* m = reach_method(t, cap, method_name, typeargs); - codegen_debugloc(c, ast); gen_send_message(c, m, args, positional); codegen_debugloc(c, NULL); @@ -863,7 +879,9 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) while(arg != NULL) { - args[i] = gen_assign_cast(c, params[i], args[i], ast_type(arg)); + ast_t* arg_type = deferred_reify(reify, ast_type(arg), c->opt); + args[i] = gen_assign_cast(c, params[i], args[i], arg_type); + ast_free_unattached(arg_type); arg = ast_sibling(arg); i++; } @@ -918,7 +936,8 @@ LLVMValueRef gen_call(compile_t* c, ast_t* ast) LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) { // This is used for structural equality in pattern matching. - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); if(ast_id(pattern_type) == TK_NOMINAL) { @@ -948,6 +967,7 @@ LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) (name == c->str_F64) ) { + ast_free_unattached(pattern_type); return gen_eq_rvalue(c, pattern, r_value, true); } } @@ -963,6 +983,8 @@ LLVMValueRef gen_pattern_eq(compile_t* c, ast_t* pattern, LLVMValueRef r_value) reach_method_t* m = reach_method(t, cap, c->str_eq, NULL); LLVMValueRef func = dispatch_function(c, t, m, l_value); + ast_free_unattached(pattern_type); + if(func == NULL) return NULL; @@ -1042,6 +1064,8 @@ static LLVMValueRef declare_ffi(compile_t* c, const char* f_name, ast_t* arg = ast_child(args); + deferred_reification_t* reify = c->frame->reify; + while(arg != NULL) { ast_t* p_type = ast_type(arg); @@ -1049,9 +1073,11 @@ static LLVMValueRef declare_ffi(compile_t* c, const char* f_name, if(p_type == NULL) p_type = ast_childidx(arg, 1); + p_type = deferred_reify(reify, p_type, c->opt); reach_type_t* pt = reach_type(c->reach, p_type); pony_assert(pt != NULL); f_params[count++] = ((compile_type_t*)pt->c_type)->use_type; + ast_free_unattached(p_type); arg = ast_sibling(arg); } @@ -1126,10 +1152,13 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) // Get the function name, +1 to skip leading @ const char* f_name = ast_name(id) + 1; + deferred_reification_t* reify = c->frame->reify; + // Get the return type. - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); // Get the function. First check if the name is in use by a global and error // if it's the case. @@ -1260,7 +1289,7 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) compile_type_t* c_t = (compile_type_t*)t->c_type; // Special case a None return value, which is used for void functions. - bool isnone = is_none(type); + bool isnone = is_none(t->ast); bool isvoid = LLVMGetReturnType(f_type) == c->void_type; if(isnone && isvoid) @@ -1273,7 +1302,7 @@ LLVMValueRef gen_ffi(compile_t* c, ast_t* ast) result = cast_ffi_arg(c, ffi_decl, ast, result, c_t->use_type, "return values"); - result = gen_assign_cast(c, c_t->use_type, result, type); + result = gen_assign_cast(c, c_t->use_type, result, t->ast_cap); return result; } diff --git a/src/libponyc/codegen/gencontrol.c b/src/libponyc/codegen/gencontrol.c index 8aee7332f1..69c54763d9 100644 --- a/src/libponyc/codegen/gencontrol.c +++ b/src/libponyc/codegen/gencontrol.c @@ -33,22 +33,24 @@ LLVMValueRef gen_seq(compile_t* c, ast_t* ast) LLVMValueRef gen_if(compile_t* c, ast_t* ast) { bool needed = is_result_needed(ast); - ast_t* type = ast_type(ast); AST_GET_CHILDREN(ast, cond, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); + LLVMValueRef c_value = gen_expr(c, cond); + + if(c_value == NULL) + return NULL; + + deferred_reification_t* reify = c->frame->reify; // We will have no type if both branches have return statements. compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; - - LLVMValueRef c_value = gen_expr(c, cond); - - if(c_value == NULL) - return NULL; + ast_free_unattached(type); + } // If the conditional is constant, generate only one branch. bool gen_left = true; @@ -93,7 +95,17 @@ LLVMValueRef gen_if(compile_t* c, ast_t* ast) if(l_value != GEN_NOVALUE) { if(needed) - l_value = gen_assign_cast(c, phi_type->use_type, l_value, left_type); + { + ast_t* left_type = ast_type(left); + + // May be NULL if we're in an ifdef with a compile_error. + if(left_type != NULL) + { + left_type = deferred_reify(reify, left_type, c->opt); + l_value = gen_assign_cast(c, phi_type->use_type, l_value, left_type); + ast_free_unattached(left_type); + } + } if(l_value == NULL) return NULL; @@ -121,7 +133,17 @@ LLVMValueRef gen_if(compile_t* c, ast_t* ast) if(r_value != GEN_NOVALUE) { if(needed) - r_value = gen_assign_cast(c, phi_type->use_type, r_value, right_type); + { + ast_t* right_type = ast_type(right); + + // May be NULL if we're in an ifdef with a compile_error. + if(right_type != NULL) + { + right_type = deferred_reify(reify, right_type, c->opt); + r_value = gen_assign_cast(c, phi_type->use_type, r_value, right_type); + ast_free_unattached(right_type); + } + } if(r_value == NULL) return NULL; @@ -159,7 +181,17 @@ LLVMValueRef gen_iftype(compile_t* c, ast_t* ast) AST_GET_CHILDREN(ast, left, right); AST_GET_CHILDREN(left, subtype, supertype, body); - if(is_subtype_constraint(subtype, supertype, NULL, c->opt)) + deferred_reification_t* reify = c->frame->reify; + + ast_t* r_sub = deferred_reify(reify, subtype, c->opt); + ast_t* r_super = deferred_reify(reify, supertype, c->opt); + + bool is_sub = is_subtype_constraint(r_sub, r_super, NULL, c->opt); + + ast_free_unattached(r_sub); + ast_free_unattached(r_super); + + if(is_sub) return gen_expr(c, body); return gen_expr(c, right); @@ -170,14 +202,16 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, cond, body, else_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef init_block = codegen_block(c, "while_init"); LLVMBasicBlockRef body_block = codegen_block(c, "while_body"); @@ -219,7 +253,11 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) LLVMValueRef l_value = gen_expr(c, body); if(needed) + { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); l_value = gen_assign_cast(c, phi_type->use_type, l_value, body_type); + ast_free_unattached(body_type); + } if(l_value == NULL) return NULL; @@ -260,7 +298,11 @@ LLVMValueRef gen_while(compile_t* c, ast_t* ast) return NULL; if(needed) + { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); r_value = gen_assign_cast(c, phi_type->use_type, r_value, else_type); + ast_free_unattached(else_type); + } else_from = LLVMGetInsertBlock(c->builder); LLVMBuildBr(c->builder, post_block); @@ -292,14 +334,16 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, body, cond, else_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef body_block = codegen_block(c, "repeat_body"); LLVMBasicBlockRef cond_block = codegen_block(c, "repeat_cond"); @@ -328,7 +372,11 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) LLVMValueRef value = gen_expr(c, body); if(needed) + { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); value = gen_assign_cast(c, phi_type->use_type, value, body_type); + ast_free_unattached(body_type); + } if(value == NULL) return NULL; @@ -378,7 +426,11 @@ LLVMValueRef gen_repeat(compile_t* c, ast_t* ast) return NULL; if(needed) + { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); else_value = gen_assign_cast(c, phi_type->use_type, else_value, else_type); + ast_free_unattached(else_type); + } if(else_value != GEN_NOVALUE) { @@ -417,8 +469,6 @@ LLVMValueRef gen_break(compile_t* c, ast_t* ast) { target = c->frame->break_novalue_target; } else { - ast_t* body_type = ast_type(body); - // Get the break target. target = c->frame->break_target; @@ -433,7 +483,10 @@ LLVMValueRef gen_break(compile_t* c, ast_t* ast) { // Cast it to the phi type if we need to. LLVMTypeRef phi_type = LLVMTypeOf(post_phi); + ast_t* body_type = deferred_reify(c->frame->reify, ast_type(body), + c->opt); value = gen_assign_cast(c, phi_type, value, body_type); + ast_free_unattached(body_type); } if(value == NULL) @@ -489,7 +542,9 @@ LLVMValueRef gen_return(compile_t* c, ast_t* ast) if(LLVMGetTypeKind(r_type) != LLVMVoidTypeKind) { - LLVMValueRef ret = gen_assign_cast(c, r_type, value, ast_type(expr)); + ast_t* type = deferred_reify(c->frame->reify, ast_type(expr), c->opt); + LLVMValueRef ret = gen_assign_cast(c, r_type, value, type); + ast_free_unattached(type); codegen_scope_lifetime_end(c); LLVMBuildRet(c->builder, ret); } else { @@ -506,15 +561,17 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) bool needed = is_result_needed(ast); AST_GET_CHILDREN(ast, body, else_clause, then_clause); - ast_t* type = ast_type(ast); - ast_t* body_type = ast_type(body); - ast_t* else_type = ast_type(else_clause); + deferred_reification_t* reify = c->frame->reify; compile_type_t* phi_type = NULL; // We will have no type if both branches have return statements. if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) + { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); phi_type = (compile_type_t*)reach_type(c->reach, type)->c_type; + ast_free_unattached(type); + } LLVMBasicBlockRef block = LLVMGetInsertBlock(c->builder); LLVMBasicBlockRef else_block = codegen_block(c, "try_else"); @@ -534,8 +591,10 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) { if(needed) { + ast_t* body_type = deferred_reify(reify, ast_type(body), c->opt); body_value = gen_assign_cast(c, phi_type->use_type, body_value, body_type); + ast_free_unattached(body_type); } if(body_value == NULL) @@ -572,8 +631,10 @@ LLVMValueRef gen_try(compile_t* c, ast_t* ast) { if(needed) { + ast_t* else_type = deferred_reify(reify, ast_type(else_clause), c->opt); else_value = gen_assign_cast(c, phi_type->use_type, else_value, else_type); + ast_free_unattached(else_type); } if(else_value == NULL) diff --git a/src/libponyc/codegen/gendesc.c b/src/libponyc/codegen/gendesc.c index 443e756ccd..18dab986e0 100644 --- a/src/libponyc/codegen/gendesc.c +++ b/src/libponyc/codegen/gendesc.c @@ -62,7 +62,7 @@ static LLVMValueRef make_unbox_function(compile_t* c, reach_type_t* t, LLVMTypeRef unbox_type = LLVMFunctionType(ret_type, params, count, false); LLVMValueRef unbox_fun = codegen_addfun(c, unbox_name, unbox_type, true); - codegen_startfun(c, unbox_fun, NULL, NULL, false); + codegen_startfun(c, unbox_fun, NULL, NULL, NULL, false); // Extract the primitive type from element 1 and call the real function. LLVMValueRef this_ptr = LLVMGetParam(unbox_fun, 0); diff --git a/src/libponyc/codegen/genexe.c b/src/libponyc/codegen/genexe.c index 8597753870..6f2f490574 100644 --- a/src/libponyc/codegen/genexe.c +++ b/src/libponyc/codegen/genexe.c @@ -100,7 +100,7 @@ LLVMValueRef gen_main(compile_t* c, reach_type_t* t_main, reach_type_t* t_env) LLVMTypeRef ftype = LLVMFunctionType(c->i32, params, 3, false); LLVMValueRef func = LLVMAddFunction(c->module, "main", ftype); - codegen_startfun(c, func, NULL, NULL, false); + codegen_startfun(c, func, NULL, NULL, NULL, false); LLVMBasicBlockRef start_fail_block = codegen_block(c, "start_fail"); LLVMBasicBlockRef post_block = codegen_block(c, "post"); diff --git a/src/libponyc/codegen/genfun.c b/src/libponyc/codegen/genfun.c index ceddec04d4..5aa9bb864f 100644 --- a/src/libponyc/codegen/genfun.c +++ b/src/libponyc/codegen/genfun.c @@ -327,13 +327,13 @@ static void make_prototype(compile_t* c, reach_type_t* t, } } -static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, - uint32_t index, LLVMValueRef handler, LLVMTypeRef fun_type, - LLVMTypeRef msg_type) +static void add_dispatch_case(compile_t* c, reach_type_t* t, + reach_param_t* params, uint32_t index, LLVMValueRef handler, + LLVMTypeRef fun_type, LLVMTypeRef msg_type) { // Add a case to the dispatch function to handle this message. compile_type_t* c_t = (compile_type_t*)t->c_type; - codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, false); + codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, NULL, false); LLVMBasicBlockRef block = codegen_block(c, "handler"); LLVMValueRef id = LLVMConstInt(c->i32, index, false); LLVMAddCase(c_t->dispatch_switch, id, block); @@ -345,7 +345,7 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, LLVMValueRef msg = LLVMBuildBitCast(c->builder, LLVMGetParam(c_t->dispatch_fn, 2), msg_type, ""); - int count = LLVMCountParamTypes(fun_type); + size_t count = LLVMCountParamTypes(fun_type); size_t params_buf_size = count * sizeof(LLVMTypeRef); LLVMTypeRef* param_types = (LLVMTypeRef*)ponyint_pool_alloc_size(params_buf_size); @@ -355,42 +355,34 @@ static void add_dispatch_case(compile_t* c, reach_type_t* t, ast_t* params, LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(args_buf_size); args[0] = LLVMBuildBitCast(c->builder, this_ptr, c_t->use_type, ""); - ast_t* param = ast_child(params); - - for(int i = 1; i < count; i++) + for(int i = 1; i < (int)count; i++) { LLVMValueRef field = LLVMBuildStructGEP(c->builder, msg, i + 2, ""); args[i] = LLVMBuildLoad(c->builder, field, ""); - args[i] = gen_assign_cast(c, param_types[i], args[i], ast_type(param)); - param = ast_sibling(param); + args[i] = gen_assign_cast(c, param_types[i], args[i], + params[i - 1].type->ast_cap); } // Trace the message. - param = ast_child(params); bool need_trace = false; - while(param != NULL) + for(size_t i = 0; i < count - 1; i++) { - ast_t* param_type = ast_type(param); - if(gentrace_needed(c, param_type, param_type)) + if(gentrace_needed(c, params[i].type->ast_cap, params[i].type->ast_cap)) { need_trace = true; break; } - - param = ast_sibling(param); } if(need_trace) { - param = ast_child(params); gencall_runtime(c, "pony_gc_recv", &ctx, 1, ""); - for(int i = 1; i < count; i++) + for(size_t i = 1; i < count; i++) { - ast_t* param_type = ast_type(param); - gentrace(c, ctx, args[i], args[i], param_type, param_type); - param = ast_sibling(param); + gentrace(c, ctx, args[i], args[i], params[i - 1].type->ast_cap, + params[i - 1].type->ast_cap); } gencall_runtime(c, "pony_recv_done", &ctx, 1, ""); @@ -437,12 +429,10 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) compile_method_t* c_m = (compile_method_t*)m->c_method; pony_assert(c_m->func != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, ast_id(cap) == TK_AT); name_params(c, t, m, c_m->func); @@ -458,8 +448,11 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) if(value != GEN_NOVALUE) { - if(finaliser || ((ast_id(cap) == TK_AT) && is_none(result))) + ast_t* r_result = deferred_reify(m->fun, result, c->opt); + + if(finaliser || ((ast_id(cap) == TK_AT) && is_none(r_result))) { + ast_free_unattached(r_result); codegen_scope_lifetime_end(c); codegen_debugloc(c, ast_childlast(body)); LLVMBuildRetVoid(c->builder); @@ -469,13 +462,20 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) // If the result type is known to be a tuple, do the correct assignment // cast even if the body type is not a tuple. - ast_t* body_type = ast_type(body); + ast_t* body_type = deferred_reify(m->fun, ast_type(body), c->opt); if((ast_id(result) == TK_TUPLETYPE) && (ast_id(body_type) != TK_TUPLETYPE)) - body_type = result; + { + ast_free_unattached(body_type); + body_type = r_result; + r_result = NULL; + } LLVMValueRef ret = gen_assign_cast(c, r_type, value, body_type); + ast_free_unattached(body_type); + ast_free_unattached(r_result); + if(ret == NULL) return false; @@ -489,8 +489,6 @@ static bool genfun_fun(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); - ast_free_unattached(r_fun); - return true; } @@ -500,13 +498,12 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) pony_assert(c_m->func != NULL); pony_assert(c_m->func_handler != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); // Generate the handler. - codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, m->fun, + false); name_params(c, t, m, c_m->func_handler); LLVMValueRef value = gen_expr(c, body); @@ -521,7 +518,7 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); // Generate the sender. - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, m->fun, false); size_t buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* param_vals = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); LLVMGetParams(c_m->func, param_vals); @@ -537,11 +534,9 @@ static bool genfun_be(compile_t* c, reach_type_t* t, reach_method_t* m) // Add the dispatch case. LLVMTypeRef msg_type_ptr = LLVMPointerType(c_m->msg_type, 0); - add_dispatch_case(c, t, params, m->vtable_index, c_m->func_handler, + add_dispatch_case(c, t, m->params, m->vtable_index, c_m->func_handler, c_m->func_type, msg_type_ptr); - ast_free_unattached(r_fun); - return true; } @@ -551,12 +546,10 @@ static bool genfun_new(compile_t* c, reach_type_t* t, reach_method_t* m) compile_method_t* c_m = (compile_method_t*)m->c_method; pony_assert(c_m->func != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, false); name_params(c, t, m, c_m->func); LLVMValueRef value = gen_expr(c, body); @@ -578,8 +571,6 @@ static bool genfun_new(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); - ast_free_unattached(r_fun); - return true; } @@ -589,13 +580,12 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) pony_assert(c_m->func != NULL); pony_assert(c_m->func_handler != NULL); - ast_t* r_fun = deferred_reify(m->fun, m->fun->ast, c->opt); - - AST_GET_CHILDREN(r_fun, cap, id, typeparams, params, result, can_error, + AST_GET_CHILDREN(m->fun->ast, cap, id, typeparams, params, result, can_error, body); // Generate the handler. - codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, false); + codegen_startfun(c, c_m->func_handler, c_m->di_file, c_m->di_method, m->fun, + false); name_params(c, t, m, c_m->func_handler); LLVMValueRef value = gen_expr(c, body); @@ -608,7 +598,7 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) codegen_finishfun(c); // Generate the sender. - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, m->fun, false); size_t buf_size = (m->param_count + 1) * sizeof(LLVMValueRef); LLVMValueRef* param_vals = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); LLVMGetParams(c_m->func, param_vals); @@ -624,11 +614,9 @@ static bool genfun_newbe(compile_t* c, reach_type_t* t, reach_method_t* m) // Add the dispatch case. LLVMTypeRef msg_type_ptr = LLVMPointerType(c_m->msg_type, 0); - add_dispatch_case(c, t, params, m->vtable_index, c_m->func_handler, + add_dispatch_case(c, t, m->params, m->vtable_index, c_m->func_handler, c_m->func_type, msg_type_ptr); - ast_free_unattached(r_fun); - return true; } @@ -665,7 +653,7 @@ static bool genfun_implicit_final(compile_t* c, reach_type_t* t, { compile_method_t* c_m = (compile_method_t*)m->c_method; - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); call_embed_finalisers(c, t, NULL, gen_this(c, NULL)); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); @@ -709,7 +697,7 @@ static bool genfun_allocator(compile_t* c, reach_type_t* t) LLVMAddAttributeAtIndex(fun, LLVMAttributeReturnIndex, deref_attr); LLVMAddAttributeAtIndex(fun, LLVMAttributeReturnIndex, align_attr); } - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMValueRef result; @@ -748,7 +736,8 @@ static bool genfun_forward(compile_t* c, reach_type_t* t, pony_assert(m2 != m); compile_method_t* c_m2 = (compile_method_t*)m2->c_method; - codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->cap == TK_AT); + codegen_startfun(c, c_m->func, c_m->di_file, c_m->di_method, m->fun, + m->cap == TK_AT); int count = LLVMCountParams(c_m->func); size_t buf_size = count * sizeof(LLVMValueRef); @@ -1014,7 +1003,7 @@ void genfun_primitive_calls(compile_t* c) const char* fn_name = genname_program_fn(c->filename, "primitives_init"); c->primitives_init = LLVMAddFunction(c->module, fn_name, fn_type); - codegen_startfun(c, c->primitives_init, NULL, NULL, false); + codegen_startfun(c, c->primitives_init, NULL, NULL, NULL, false); primitive_call(c, c->str__init); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); @@ -1027,7 +1016,7 @@ void genfun_primitive_calls(compile_t* c) const char* fn_name = genname_program_fn(c->filename, "primitives_final"); c->primitives_final = LLVMAddFunction(c->module, fn_name, fn_type); - codegen_startfun(c, c->primitives_final, NULL, NULL, false); + codegen_startfun(c, c->primitives_final, NULL, NULL, NULL, false); primitive_call(c, c->str__final); LLVMBuildRetVoid(c->builder); codegen_finishfun(c); diff --git a/src/libponyc/codegen/genident.c b/src/libponyc/codegen/genident.c index d5dc87fef2..c393daff97 100644 --- a/src/libponyc/codegen/genident.c +++ b/src/libponyc/codegen/genident.c @@ -441,8 +441,6 @@ static LLVMValueRef gen_is_value(compile_t* c, ast_t* left_type, LLVMValueRef gen_is(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -450,18 +448,23 @@ LLVMValueRef gen_is(compile_t* c, ast_t* ast) if((l_value == NULL) || (r_value == NULL)) return NULL; + deferred_reification_t* reify = c->frame->reify; + ast_t* left_type = deferred_reify(reify, ast_type(left), c->opt); + ast_t* right_type = deferred_reify(reify, ast_type(right), c->opt); + codegen_debugloc(c, ast); LLVMValueRef result = gen_is_value(c, left_type, right_type, l_value, r_value); codegen_debugloc(c, NULL); + + ast_free_unattached(left_type); + ast_free_unattached(right_type); return result; } LLVMValueRef gen_isnt(compile_t* c, ast_t* ast) { AST_GET_CHILDREN(ast, left, right); - ast_t* left_type = ast_type(left); - ast_t* right_type = ast_type(right); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -469,11 +472,18 @@ LLVMValueRef gen_isnt(compile_t* c, ast_t* ast) if((l_value == NULL) || (r_value == NULL)) return NULL; + deferred_reification_t* reify = c->frame->reify; + ast_t* left_type = deferred_reify(reify, ast_type(left), c->opt); + ast_t* right_type = deferred_reify(reify, ast_type(right), c->opt); + codegen_debugloc(c, ast); LLVMValueRef result = gen_is_value(c, left_type, right_type, l_value, r_value); result = LLVMBuildNot(c->builder, result, ""); codegen_debugloc(c, NULL); + + ast_free_unattached(left_type); + ast_free_unattached(right_type); return result; } @@ -495,7 +505,7 @@ void gen_is_tuple_fun(compile_t* c, reach_type_t* t) c_m->func_type = LLVMFunctionType(c->i1, params, 3, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); LLVMValueRef l_value = LLVMGetParam(codegen_fun(c), 0); LLVMValueRef r_value = LLVMGetParam(codegen_fun(c), 1); LLVMValueRef r_id = LLVMGetParam(codegen_fun(c), 2); diff --git a/src/libponyc/codegen/genmatch.c b/src/libponyc/codegen/genmatch.c index c20c55bbc0..1b4c2f9125 100644 --- a/src/libponyc/codegen/genmatch.c +++ b/src/libponyc/codegen/genmatch.c @@ -35,7 +35,8 @@ static bool static_match(compile_t* c, LLVMValueRef value, ast_t* type, static ast_t* eq_param_type(compile_t* c, ast_t* pattern) { - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); deferred_reification_t* fun = lookup(NULL, pattern, pattern_type, c->str_eq); AST_GET_CHILDREN(fun->ast, cap, id, typeparams, params, result, partial); @@ -44,6 +45,7 @@ static ast_t* eq_param_type(compile_t* c, ast_t* pattern) ast_t* r_type = deferred_reify(fun, type, c->opt); + ast_free_unattached(pattern_type); deferred_reify_free(fun); return r_type; } @@ -403,7 +405,8 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, { // Here, ptr is a pointer to a tuple field. It could be a primitive, an // object, or a nested tuple. - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); ast_t* the_case = ast_parent(pattern); match_weight_t weight; @@ -417,7 +420,10 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, pattern_type, next_block, weight)) + { + ast_free_unattached(pattern_type); return false; + } // We now know that ptr points to something of type pattern_type, and that // it isn't a boxed primitive or tuple, as that would go through the other @@ -429,7 +435,10 @@ static bool dynamic_capture_ptr(compile_t* c, LLVMValueRef ptr, ptr = LLVMBuildBitCast(c->builder, ptr, ptr_type, ""); LLVMValueRef value = LLVMBuildLoad(c->builder, ptr, ""); - return gen_assign_value(c, pattern, value, pattern_type) != NULL; + LLVMValueRef r = gen_assign_value(c, pattern, value, pattern_type); + + ast_free_unattached(pattern_type); + return r != NULL; } static bool dynamic_match_ptr(compile_t* c, LLVMValueRef ptr, @@ -494,7 +503,8 @@ static bool dynamic_value_object(compile_t* c, LLVMValueRef object, static bool dynamic_capture_object(compile_t* c, LLVMValueRef object, LLVMValueRef desc, ast_t* pattern, LLVMBasicBlockRef next_block) { - ast_t* pattern_type = ast_type(pattern); + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); // Build a base pointer that skips the object header. LLVMValueRef ptr = gendesc_ptr_to_fields(c, object, desc); @@ -511,12 +521,18 @@ static bool dynamic_capture_object(compile_t* c, LLVMValueRef object, // Check the runtime type. We pass a pointer to the fields because we may // still need to match a tuple type inside a type expression. if(!check_type(c, ptr, desc, pattern_type, next_block, weight)) + { + ast_free_unattached(pattern_type); return false; + } // As long as the type is correct, we can assign it, with gen_assign_value() // handling boxing and unboxing. We pass the type of the pattern as the type // of the object. - return gen_assign_value(c, pattern, object, pattern_type) != NULL; + LLVMValueRef r = gen_assign_value(c, pattern, object, pattern_type); + + ast_free_unattached(pattern_type); + return r != NULL; } static bool dynamic_match_object(compile_t* c, LLVMValueRef object, @@ -641,7 +657,6 @@ static bool static_capture(compile_t* c, LLVMValueRef value, ast_t* type, ast_t* pattern, LLVMBasicBlockRef next_block) { // The pattern is a capture. Make sure we are the right type, then assign. - ast_t* pattern_type = ast_type(pattern); if(ast_id(pattern) == TK_MATCH_CAPTURE) { @@ -650,7 +665,14 @@ static bool static_capture(compile_t* c, LLVMValueRef value, ast_t* type, return false; } - if(!is_subtype(type, pattern_type, NULL, c->opt)) + ast_t* pattern_type = deferred_reify(c->frame->reify, ast_type(pattern), + c->opt); + + bool is_sub = is_subtype(type, pattern_type, NULL, c->opt); + + ast_free_unattached(pattern_type); + + if(!is_sub) { // Switch to dynamic capture. pony_assert(LLVMTypeOf(value) == c->object_ptr); @@ -738,8 +760,9 @@ static bool case_body(compile_t* c, ast_t* body, if(is_result_needed(body)) { - ast_t* body_type = ast_type(body); + ast_t* body_type = deferred_reify(c->frame->reify, ast_type(body), c->opt); body_value = gen_assign_cast(c, phi_type, body_value, body_type); + ast_free_unattached(body_type); if(body_value == NULL) return false; @@ -756,19 +779,27 @@ static bool case_body(compile_t* c, ast_t* body, LLVMValueRef gen_match(compile_t* c, ast_t* ast) { bool needed = is_result_needed(ast); - ast_t* type = ast_type(ast); AST_GET_CHILDREN(ast, match_expr, cases, else_expr); // We will have no type if all cases jump away. LLVMTypeRef phi_type = NULL; + deferred_reification_t* reify = c->frame->reify; + if(needed && !ast_checkflag(ast, AST_FLAG_JUMPS_AWAY)) { + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t_phi = reach_type(c->reach, type); phi_type = ((compile_type_t*)t_phi->c_type)->use_type; + ast_free_unattached(type); } - ast_t* match_type = alias(ast_type(match_expr)); + ast_t* expr_type = deferred_reify(reify, ast_type(match_expr), c->opt); + ast_t* match_type = alias(expr_type); + + if(match_type != expr_type) + ast_free_unattached(expr_type); + LLVMValueRef match_value = gen_expr(c, match_expr); LLVMBasicBlockRef pattern_block = codegen_block(c, "case_pattern"); @@ -814,10 +845,14 @@ LLVMValueRef gen_match(compile_t* c, ast_t* ast) LLVMPositionBuilderAtEnd(c->builder, pattern_block); codegen_pushscope(c, the_case); - ast_t* pattern_type = ast_type(the_case); + ast_t* pattern_type = deferred_reify(reify, ast_type(the_case), c->opt); bool ok = true; - if(is_matchtype(match_type, pattern_type, c->opt) != MATCHTYPE_ACCEPT) + matchtype_t match = is_matchtype(match_type, pattern_type, c->opt); + + ast_free_unattached(pattern_type); + + if(match != MATCHTYPE_ACCEPT) { // If there's no possible match, jump directly to the next block. LLVMBuildBr(c->builder, next_block); diff --git a/src/libponyc/codegen/genoperator.c b/src/libponyc/codegen/genoperator.c index 5de949cb25..5939095fdf 100644 --- a/src/libponyc/codegen/genoperator.c +++ b/src/libponyc/codegen/genoperator.c @@ -78,8 +78,9 @@ static LLVMValueRef make_divmod(compile_t* c, ast_t* left, ast_t* right, build_binop build_f, build_binop build_ui, build_binop build_si, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -239,8 +240,9 @@ static LLVMValueRef make_cmp(compile_t* c, ast_t* left, ast_t* right, LLVMRealPredicate cmp_f, LLVMIntPredicate cmp_si, LLVMIntPredicate cmp_ui, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -430,6 +432,8 @@ static bool assign_tuple(compile_t* c, ast_t* left, ast_t* r_type, static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, LLVMValueRef r_value) { + deferred_reification_t* reify = c->frame->reify; + switch(ast_id(left)) { case TK_SEQ: @@ -460,18 +464,30 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, { // The result is the previous value of the field. LLVMValueRef l_value = gen_fieldptr(c, left); - ast_t* p_type = ast_type(ast_child(left)); - ast_t* l_type = ast_type(left); - return assign_field(c, l_value, r_value, p_type, l_type, r_type); + ast_t* p_type = deferred_reify(reify, ast_type(ast_child(left)), c->opt); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + + LLVMValueRef ret = assign_field(c, l_value, r_value, p_type, l_type, + r_type); + + ast_free_unattached(p_type); + ast_free_unattached(l_type); + return ret; } case TK_TUPLEELEMREF: { // The result is the previous value of the tuple element. LLVMValueRef l_value = gen_tupleelemptr(c, left); - ast_t* p_type = ast_type(ast_child(left)); - ast_t* l_type = ast_type(left); - return assign_field(c, l_value, r_value, p_type, l_type, r_type); + ast_t* p_type = deferred_reify(reify, ast_type(ast_child(left)), c->opt); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + + LLVMValueRef r = assign_field(c, l_value, r_value, p_type, l_type, + r_type); + + ast_free_unattached(p_type); + ast_free_unattached(l_type); + return r; } case TK_EMBEDREF: @@ -486,8 +502,11 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, const char* name = ast_name(ast_child(left)); codegen_local_lifetime_start(c, name); LLVMValueRef l_value = codegen_getlocal(c, name); - ast_t* l_type = ast_type(left); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); + LLVMValueRef ret = assign_local(c, l_value, r_value, l_type, r_type); + + ast_free_unattached(l_type); return ret; } @@ -521,8 +540,11 @@ static LLVMValueRef assign_rvalue(compile_t* c, ast_t* left, ast_t* r_type, const char* name = ast_name(left); codegen_local_lifetime_start(c, name); LLVMValueRef l_value = codegen_getlocal(c, name); - ast_t* l_type = ast_type(ast_parent(left)); + ast_t* l_type = deferred_reify(reify, ast_type(ast_parent(left)), c->opt); + LLVMValueRef ret = assign_local(c, l_value, r_value, l_type, r_type); + + ast_free_unattached(l_type); return ret; } @@ -587,8 +609,9 @@ LLVMValueRef gen_add(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFAdd, LLVMConstAdd, LLVMBuildFAdd, LLVMBuildAdd); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFAdd, LLVMConstAdd, make_unsafe_fadd, sign ? LLVMBuildNSWAdd : LLVMBuildNUWAdd); @@ -600,8 +623,9 @@ LLVMValueRef gen_sub(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFSub, LLVMConstSub, LLVMBuildFSub, LLVMBuildSub); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFSub, LLVMConstSub, make_unsafe_fsub, sign ? LLVMBuildNSWSub : LLVMBuildNUWSub); @@ -613,8 +637,9 @@ LLVMValueRef gen_mul(compile_t* c, ast_t* left, ast_t* right, bool safe) return make_binop(c, left, right, LLVMConstFMul, LLVMConstMul, LLVMBuildFMul, LLVMBuildMul); - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); return make_binop(c, left, right, LLVMConstFMul, LLVMConstMul, make_unsafe_fmul, sign ? LLVMBuildNSWMul : LLVMBuildNUWMul); @@ -653,8 +678,9 @@ LLVMValueRef gen_neg(compile_t* c, ast_t* ast, bool safe) if(safe) return LLVMBuildNeg(c->builder, value, ""); - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); if(sign) return LLVMBuildNSWNeg(c->builder, value, ""); @@ -697,8 +723,9 @@ LLVMValueRef gen_shl(compile_t* c, ast_t* left, ast_t* right, bool safe) return LLVMBuildShl(c->builder, l_value, select, ""); } - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef result = LLVMBuildShl(c->builder, l_value, r_value, ""); @@ -713,8 +740,9 @@ LLVMValueRef gen_shl(compile_t* c, ast_t* left, ast_t* right, bool safe) LLVMValueRef gen_shr(compile_t* c, ast_t* left, ast_t* right, bool safe) { (void)safe; - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); LLVMValueRef r_value = gen_expr(c, right); @@ -826,9 +854,11 @@ LLVMValueRef gen_not(compile_t* c, ast_t* ast) if(value == NULL) return NULL; - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); + bool bool_type = is_bool(type); + ast_free_unattached(type); - if(is_bool(type)) + if(bool_type) { if(LLVMIsAConstantInt(value)) { @@ -856,8 +886,9 @@ LLVMValueRef gen_eq(compile_t* c, ast_t* left, ast_t* right, bool safe) LLVMValueRef gen_eq_rvalue(compile_t* c, ast_t* left, LLVMValueRef r_value, bool safe) { - ast_t* type = ast_type(left); + ast_t* type = deferred_reify(c->frame->reify, ast_type(left), c->opt); bool sign = is_signed(type); + ast_free_unattached(type); LLVMValueRef l_value = gen_expr(c, left); return make_cmp_value(c, sign, l_value, r_value, LLVMRealOEQ, LLVMIntEQ, @@ -899,7 +930,9 @@ LLVMValueRef gen_assign(compile_t* c, ast_t* ast) return NULL; codegen_debugloc(c, ast); - LLVMValueRef result = assign_rvalue(c, left, ast_type(right), r_value); + ast_t* type = deferred_reify(c->frame->reify, ast_type(right), c->opt); + LLVMValueRef result = assign_rvalue(c, left, type, r_value); + ast_free_unattached(type); codegen_debugloc(c, NULL); return result; } diff --git a/src/libponyc/codegen/genprim.c b/src/libponyc/codegen/genprim.c index c94af9d23a..1818944ea2 100644 --- a/src/libponyc/codegen/genprim.c +++ b/src/libponyc/codegen/genprim.c @@ -43,7 +43,7 @@ static void start_function(compile_t* c, reach_type_t* t, reach_method_t* m, c_m->func_type = LLVMFunctionType(result, params, count, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); genfun_param_attrs(c, t, m, c_m->func); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); } static void box_function(compile_t* c, generate_box_fn gen, void* gen_data) @@ -737,7 +737,7 @@ static void trace_array_elements(compile_t* c, reach_type_t* t, void genprim_array_trace(compile_t* c, reach_type_t* t) { compile_type_t* c_t = (compile_type_t*)t->c_type; - codegen_startfun(c, c_t->trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->trace_fn, LLVMExternalLinkage); LLVMValueRef ctx = LLVMGetParam(c_t->trace_fn, 0); @@ -765,7 +765,7 @@ void genprim_array_serialise_trace(compile_t* c, reach_type_t* t) c_t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name), c->trace_type, true); - codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_trace_fn, LLVMExternalLinkage); @@ -820,7 +820,7 @@ void genprim_array_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -947,7 +947,7 @@ void genprim_array_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); @@ -1031,7 +1031,7 @@ void genprim_string_serialise_trace(compile_t* c, reach_type_t* t) c_t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_trace_fn, LLVMExternalLinkage); @@ -1064,7 +1064,7 @@ void genprim_string_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -1134,7 +1134,7 @@ void genprim_string_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); @@ -1917,7 +1917,7 @@ static void make_cpuid(compile_t* c) LLVMTypeRef f_type = LLVMFunctionType(r_type, &c->i32, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.cpuid", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMValueRef cpuid = LLVMConstInlineAsm(f_type, "cpuid", "={ax},={bx},={cx},={dx},{ax}", false, false); @@ -1946,7 +1946,7 @@ static void make_rdtscp(compile_t* c) f_type = LLVMFunctionType(c->i64, &i32_ptr, 1, false); LLVMValueRef fun = codegen_addfun(c, "internal.x86.rdtscp", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); // Cast i32* to i8* and call the intrinsic. LLVMValueRef arg = LLVMGetParam(fun, 0); @@ -2017,7 +2017,7 @@ void genprim_signature(compile_t* c) LLVMTypeRef f_type = LLVMFunctionType(c_t->use_type, NULL, 0, false); LLVMValueRef fun = codegen_addfun(c, "internal.signature", f_type, false); LLVMSetFunctionCallConv(fun, LLVMCCallConv); - codegen_startfun(c, fun, NULL, NULL, false); + codegen_startfun(c, fun, NULL, NULL, NULL, false); LLVMBuildRet(c->builder, g_array); codegen_finishfun(c); } diff --git a/src/libponyc/codegen/genreference.c b/src/libponyc/codegen/genreference.c index 3a07a74749..31c4921dc2 100644 --- a/src/libponyc/codegen/genreference.c +++ b/src/libponyc/codegen/genreference.c @@ -86,8 +86,10 @@ LLVMValueRef gen_fieldptr(compile_t* c, ast_t* ast) if(l_value == NULL) return NULL; - ast_t* l_type = ast_type(left); - return make_fieldptr(c, l_value, l_type, right); + ast_t* l_type = deferred_reify(c->frame->reify, ast_type(left), c->opt); + LLVMValueRef ret = make_fieldptr(c, l_value, l_type, right); + ast_free_unattached(l_type); + return ret; } LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) @@ -99,14 +101,20 @@ LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) if(field == NULL) return NULL; - ast_t* type = ast_type(right); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(right), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; field = LLVMBuildLoad(c->builder, field, ""); - LLVMValueRef metadata = tbaa_metadata_for_type(c, ast_type(left)); + type = deferred_reify(reify, ast_type(left), c->opt); + LLVMValueRef metadata = tbaa_metadata_for_type(c, type); + ast_free_unattached(type); + #if PONY_LLVM >= 400 tbaa_tag(c, metadata, field); #else @@ -114,7 +122,7 @@ LLVMValueRef gen_fieldload(compile_t* c, ast_t* ast) LLVMSetMetadata(field, LLVMGetMDKindID(id, sizeof(id) - 1), metadata); #endif - return gen_assign_cast(c, c_t->use_type, field, type); + return gen_assign_cast(c, c_t->use_type, field, t->ast_cap); } @@ -146,14 +154,18 @@ LLVMValueRef gen_tupleelemptr(compile_t* c, ast_t* ast) if(l_value == NULL) return NULL; - ast_t* type = ast_type(ast); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); pony_assert(t != NULL); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; - ast_t* l_type = ast_type(left); + ast_t* l_type = deferred_reify(reify, ast_type(left), c->opt); LLVMValueRef value = make_tupleelemptr(c, l_value, l_type, right); - return gen_assign_cast(c, c_t->use_type, value, type); + ast_free_unattached(l_type); + return gen_assign_cast(c, c_t->use_type, value, t->ast_cap); } LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) @@ -163,11 +175,16 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) if(ast_sibling(child) == NULL) return gen_expr(c, child); - ast_t* type = ast_type(ast); + deferred_reification_t* reify = c->frame->reify; + + ast_t* type = deferred_reify(reify, ast_type(ast), c->opt); // If we contain '_', we have no usable value. if(contains_dontcare(type)) + { + ast_free_unattached(type); return GEN_NOTNEEDED; + } reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; @@ -198,7 +215,9 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) return GEN_NOTNEEDED; } - value = gen_assign_cast(c, elements[i], value, ast_type(child)); + ast_t* child_type = deferred_reify(reify, ast_type(child), c->opt); + value = gen_assign_cast(c, elements[i], value, child_type); + ast_free_unattached(child_type); tuple = LLVMBuildInsertValue(c->builder, tuple, value, i++, ""); child = ast_sibling(child); } @@ -210,7 +229,6 @@ LLVMValueRef gen_tuple(compile_t* c, ast_t* ast) LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) { ast_t* id = ast_child(ast); - ast_t* type = ast_type(id); const char* name = ast_name(id); // If this local has already been generated, don't create another copy. This @@ -221,7 +239,9 @@ LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast) if(value != NULL) return GEN_NOVALUE; + ast_t* type = deferred_reify(c->frame->reify, ast_type(id), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; // All alloca should happen in the entry block of a function. @@ -274,12 +294,13 @@ LLVMValueRef gen_localload(compile_t* c, ast_t* ast) if(local_ptr == NULL) return NULL; - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; LLVMValueRef value = LLVMBuildLoad(c->builder, local_ptr, ""); - return gen_assign_cast(c, c_t->use_type, value, type); + return gen_assign_cast(c, c_t->use_type, value, t->ast_cap); } LLVMValueRef gen_addressof(compile_t* c, ast_t* ast) @@ -435,7 +456,10 @@ LLVMValueRef gen_digestof(compile_t* c, ast_t* ast) { ast_t* expr = ast_child(ast); LLVMValueRef value = gen_expr(c, expr); - return gen_digestof_value(c, ast_type(expr), value); + ast_t* type = deferred_reify(c->frame->reify, ast_type(expr), c->opt); + LLVMValueRef ret = gen_digestof_value(c, type, value); + ast_free_unattached(type); + return ret; } void gen_digestof_fun(compile_t* c, reach_type_t* t) @@ -452,7 +476,7 @@ void gen_digestof_fun(compile_t* c, reach_type_t* t) c_m->func_type = LLVMFunctionType(c->i64, &c_t->structure_ptr, 1, false); c_m->func = codegen_addfun(c, m->full_name, c_m->func_type, true); - codegen_startfun(c, c_m->func, NULL, NULL, false); + codegen_startfun(c, c_m->func, NULL, NULL, NULL, false); LLVMValueRef value = LLVMGetParam(codegen_fun(c), 0); value = gen_unbox(c, t->ast_cap, value); @@ -463,8 +487,9 @@ void gen_digestof_fun(compile_t* c, reach_type_t* t) LLVMValueRef gen_int(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; lexint_t* value = ast_int(ast); @@ -485,8 +510,9 @@ LLVMValueRef gen_int(compile_t* c, ast_t* ast) LLVMValueRef gen_float(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); + ast_t* type = deferred_reify(c->frame->reify, ast_type(ast), c->opt); reach_type_t* t = reach_type(c->reach, type); + ast_free_unattached(type); compile_type_t* c_t = (compile_type_t*)t->c_type; return LLVMConstReal(c_t->primitive, ast_float(ast)); @@ -494,7 +520,6 @@ LLVMValueRef gen_float(compile_t* c, ast_t* ast) LLVMValueRef gen_string(compile_t* c, ast_t* ast) { - ast_t* type = ast_type(ast); const char* name = ast_name(ast); genned_string_t k; @@ -505,11 +530,13 @@ LLVMValueRef gen_string(compile_t* c, ast_t* ast) if(string != NULL) return string->global; - size_t len = ast_name_len(ast); - + ast_t* type = ast_type(ast); + pony_assert(is_literal(type, "String")); reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; + size_t len = ast_name_len(ast); + LLVMValueRef args[4]; args[0] = c_t->desc; args[1] = LLVMConstInt(c->intptr, len, false); diff --git a/src/libponyc/codegen/genserialise.c b/src/libponyc/codegen/genserialise.c index 1e7e3c3ce9..e150ada7c2 100644 --- a/src/libponyc/codegen/genserialise.c +++ b/src/libponyc/codegen/genserialise.c @@ -215,7 +215,7 @@ static void make_serialise(compile_t* c, reach_type_t* t) c_t->serialise_fn = codegen_addfun(c, genname_serialise(t->name), c->serialise_type, true); - codegen_startfun(c, c_t->serialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->serialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->serialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->serialise_fn, LLVMExternalLinkage); @@ -361,7 +361,7 @@ static void make_deserialise(compile_t* c, reach_type_t* t) c_t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name), c->trace_type, true); - codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, false); + codegen_startfun(c, c_t->deserialise_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->deserialise_fn, LLVMCCallConv); LLVMSetLinkage(c_t->deserialise_fn, LLVMExternalLinkage); diff --git a/src/libponyc/codegen/gentype.c b/src/libponyc/codegen/gentype.c index f96f34d501..9c38fd0080 100644 --- a/src/libponyc/codegen/gentype.c +++ b/src/libponyc/codegen/gentype.c @@ -477,7 +477,7 @@ static void make_dispatch(compile_t* c, reach_type_t* t) c_t->dispatch_fn = codegen_addfun(c, dispatch_name, c->dispatch_type, true); LLVMSetFunctionCallConv(c_t->dispatch_fn, LLVMCCallConv); LLVMSetLinkage(c_t->dispatch_fn, LLVMExternalLinkage); - codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, false); + codegen_startfun(c, c_t->dispatch_fn, NULL, NULL, NULL, false); LLVMBasicBlockRef unreachable = codegen_block(c, "unreachable"); @@ -778,7 +778,7 @@ static bool make_trace(compile_t* c, reach_type_t* t) } // Generate the trace function. - codegen_startfun(c, c_t->trace_fn, NULL, NULL, false); + codegen_startfun(c, c_t->trace_fn, NULL, NULL, NULL, false); LLVMSetFunctionCallConv(c_t->trace_fn, LLVMCCallConv); LLVMSetLinkage(c_t->trace_fn, LLVMExternalLinkage);