Fix closing over raw function pointers

This commit is contained in:
Nathan Braswell
2017-06-13 00:40:29 -04:00
parent 754ff41226
commit 6f659ece49

View File

@@ -645,37 +645,42 @@ obj c_generator (Object) {
ref_pre += "(*"
ref_post += ")"
}
if (!func_type->is_raw && (!is_function(node->function_call.func) || node->function_call.func->function.closed_variables.size())) {
if (!is_function(node->function_call.func) || node->function_call.func->function.closed_variables.size()) {
// not function, so we must be an identifier or function call return or something
// and also is closure style, so need special call
if (!dot_style_method_call) {
// lambda
if (pre_call == "" && (!func_return_type->is_void() || func_return_type->indirection)) {
var temp_ident = ast_identifier_ptr(string("temporary_return") + get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
// if is a raw function pointer closed over (or something)
if (func_type->is_raw) {
func_name = generate(node->function_call.func, enclosing_object, enclosing_func, false).one_string()
} else {
// lambda
if (pre_call == "" && (!func_return_type->is_void() || func_return_type->indirection)) {
var temp_ident = ast_identifier_ptr(string("temporary_return") + get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
}
var name_temp = generate(node->function_call.func, enclosing_object, enclosing_func, false)
call_string.pre += name_temp.pre
call_string.post += name_temp.post
func_name = name_temp.value
// should not have return var because is void
var pre_call_plus = pre_call
if (pre_call_plus != "")
pre_call_plus += " = "
var func_type = get_ast_type(node->function_call.func)
call_string.pre += string("if (")+func_name+".data) " + pre_call_plus + " ((" + type_to_c(func_type) + "_with_data) "+func_name+".func)("+func_name +".data"
if (call_string.value != "")
call_string.pre += string(",") + call_string.value
call_string.pre += ");\n"
call_string.pre += string("else ") + pre_call_plus + " ((" + type_to_c(func_type) + "_without_data) " + func_name+".func)(" + call_string.value + ");\n"
call_string.value = pre_call
call_string.value = ref_pre + call_string.value + ref_post
return call_string
}
var name_temp = generate(node->function_call.func, enclosing_object, enclosing_func, false)
call_string.pre += name_temp.pre
call_string.post += name_temp.post
func_name = name_temp.value
// should not have return var because is void
var pre_call_plus = pre_call
if (pre_call_plus != "")
pre_call_plus += " = "
var func_type = get_ast_type(node->function_call.func)
call_string.pre += string("if (")+func_name+".data) " + pre_call_plus + " ((" + type_to_c(func_type) + "_with_data) "+func_name+".func)("+func_name +".data"
if (call_string.value != "")
call_string.pre += string(",") + call_string.value
call_string.pre += ");\n"
call_string.pre += string("else ") + pre_call_plus + " ((" + type_to_c(func_type) + "_without_data) " + func_name+".func)(" + call_string.value + ");\n"
call_string.value = pre_call
call_string.value = ref_pre + call_string.value + ref_post
return call_string
}
}
if (pre_call != "") {