diff --git a/Sources/backends/metal.c b/Sources/backends/metal.c index ae4055e..33b3001 100644 --- a/Sources/backends/metal.c +++ b/Sources/backends/metal.c @@ -48,79 +48,6 @@ static void write_code(char *metal, char *directory, const char *filename) { fclose(file); } -static void find_referenced_global_for_var(variable v, global_id *globals, size_t *globals_size) { - for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { - global g = get_global(j); - if (v.index == g.var_index) { - bool found = false; - for (size_t k = 0; k < *globals_size; ++k) { - if (globals[k] == j) { - found = true; - break; - } - } - if (!found) { - globals[*globals_size] = j; - *globals_size += 1; - } - return; - } - } -} - -static void find_referenced_globals(function *f, global_id *globals, size_t *globals_size) { - if (f->block == NULL) { - // built-in - return; - } - - function *functions[256]; - size_t functions_size = 0; - - functions[functions_size] = f; - functions_size += 1; - - find_referenced_functions(f, functions, &functions_size); - - for (size_t l = 0; l < functions_size; ++l) { - uint8_t *data = functions[l]->code.o; - size_t size = functions[l]->code.size; - - size_t index = 0; - while (index < size) { - opcode *o = (opcode *)&data[index]; - switch (o->type) { - case OPCODE_MULTIPLY: - case OPCODE_DIVIDE: - case OPCODE_ADD: - case OPCODE_SUB: - case OPCODE_EQUALS: - case OPCODE_NOT_EQUALS: - case OPCODE_GREATER: - case OPCODE_GREATER_EQUAL: - case OPCODE_LESS: - case OPCODE_LESS_EQUAL: { - find_referenced_global_for_var(o->op_binary.left, globals, globals_size); - find_referenced_global_for_var(o->op_binary.right, globals, globals_size); - break; - } - case OPCODE_LOAD_MEMBER: { - find_referenced_global_for_var(o->op_load_member.from, globals, globals_size); - break; - } - case OPCODE_CALL: { - for (uint8_t i = 0; i < o->op_call.parameters_size; ++i) { - find_referenced_global_for_var(o->op_call.parameters[i], globals, globals_size); - } - break; - } - } - - index += o->size; - } - } -} - static type_id vertex_inputs[256]; static size_t vertex_inputs_size = 0; static type_id fragment_inputs[256]; @@ -296,7 +223,7 @@ static void write_functions(char *code, size_t *offset) { *offset += sprintf(&code[*offset], "\t%s _%i [[color(%i)]];\n", type_string(f->return_type.type), j, j); } *offset += sprintf(&code[*offset], "};\n\n"); - + *offset += sprintf(&code[*offset], "fragment _kong_colors_out %s(%s _%" PRIu64 " [[stage_in]]", get_name(f->name), type_string(f->parameter_types[0].type), parameter_ids[0]); for (uint8_t parameter_index = 1; parameter_index < f->parameters_size; ++parameter_index) { diff --git a/Sources/backends/util.c b/Sources/backends/util.c index c99d804..1ae9231 100644 --- a/Sources/backends/util.c +++ b/Sources/backends/util.c @@ -12,6 +12,79 @@ void indent(char *code, size_t *offset, int indentation) { *offset += sprintf(&code[*offset], str); } +static void find_referenced_global_for_var(variable v, global_id *globals, size_t *globals_size) { + for (global_id j = 0; get_global(j).type != NO_TYPE; ++j) { + global g = get_global(j); + if (v.index == g.var_index) { + bool found = false; + for (size_t k = 0; k < *globals_size; ++k) { + if (globals[k] == j) { + found = true; + break; + } + } + if (!found) { + globals[*globals_size] = j; + *globals_size += 1; + } + return; + } + } +} + +void find_referenced_globals(function *f, global_id *globals, size_t *globals_size) { + if (f->block == NULL) { + // built-in + return; + } + + function *functions[256]; + size_t functions_size = 0; + + functions[functions_size] = f; + functions_size += 1; + + find_referenced_functions(f, functions, &functions_size); + + for (size_t l = 0; l < functions_size; ++l) { + uint8_t *data = functions[l]->code.o; + size_t size = functions[l]->code.size; + + size_t index = 0; + while (index < size) { + opcode *o = (opcode *)&data[index]; + switch (o->type) { + case OPCODE_MULTIPLY: + case OPCODE_DIVIDE: + case OPCODE_ADD: + case OPCODE_SUB: + case OPCODE_EQUALS: + case OPCODE_NOT_EQUALS: + case OPCODE_GREATER: + case OPCODE_GREATER_EQUAL: + case OPCODE_LESS: + case OPCODE_LESS_EQUAL: { + find_referenced_global_for_var(o->op_binary.left, globals, globals_size); + find_referenced_global_for_var(o->op_binary.right, globals, globals_size); + break; + } + case OPCODE_LOAD_MEMBER: { + find_referenced_global_for_var(o->op_load_member.from, globals, globals_size); + break; + } + case OPCODE_CALL: { + for (uint8_t i = 0; i < o->op_call.parameters_size; ++i) { + find_referenced_global_for_var(o->op_call.parameters[i], globals, globals_size); + } + break; + } + } + + index += o->size; + } + } +} + void find_referenced_functions(function *f, function **functions, size_t *functions_size) { if (f->block == NULL) { // built-in diff --git a/Sources/backends/util.h b/Sources/backends/util.h index 56bc979..9f66f18 100644 --- a/Sources/backends/util.h +++ b/Sources/backends/util.h @@ -1,10 +1,12 @@ #pragma once #include "../functions.h" +#include "../globals.h" #include void find_referenced_functions(function *f, function **functions, size_t *functions_size); void find_referenced_types(function *f, type_id *types, size_t *types_size); +void find_referenced_globals(function *f, global_id *globals, size_t *globals_size); void indent(char *code, size_t *offset, int indentation);