aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-16 01:46:05 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-16 01:46:05 -0400
commita6be5c90ca99a4bfceb59c3a720c606b2f05fc8f (patch)
tree5b75fd167a31845253af7998f1e1680688656b81
parent52799d311e2998968baea6e91137fd64f0dad3f5 (diff)
For cached functions with no arguments, use a static var instead of a
cache table
-rw-r--r--compile.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/compile.c b/compile.c
index ae65fb4a..31c5c0ae 100644
--- a/compile.c
+++ b/compile.c
@@ -648,7 +648,19 @@ CORD compile_statement(env_t *env, ast_t *ast)
body = CORD_asprintf("{\n%r\n}", body);
env->code->funcs = CORD_all(env->code->funcs, code, " ", body, "\n");
- if (fndef->cache && fndef->cache->tag == Int) {
+ if (fndef->cache && fndef->args == NULL) { // no-args cache just uses a static var
+ CORD wrapper = CORD_all(
+ is_private ? CORD_EMPTY : "public ", ret_type_code, " ", name, "(void) {\n"
+ "static ", compile_declaration(ret_t, "cached_result"), ";\n",
+ "static bool initialized = false;\n",
+ "if (!initialized) {\n"
+ "\tcached_result = ", name, "$uncached();\n",
+ "\tinitialized = true;\n",
+ "}\n",
+ "return cached_result;\n"
+ "}\n");
+ env->code->funcs = CORD_cat(env->code->funcs, wrapper);
+ } else if (fndef->cache && fndef->cache->tag == Int) {
int64_t cache_size = Int64$from_text(Match(fndef->cache, Int)->str, NULL);
const char *arg_type_name = heap_strf("%s$args", Match(fndef->name, Var)->name);
ast_t *args_def = FakeAST(StructDef, .name=arg_type_name, .fields=fndef->args);
@@ -677,9 +689,9 @@ CORD compile_statement(env_t *env, ast_t *ast)
"static table_t cache = {};\n",
compile_type(args_t), " args = {", all_args, "};\n"
"const TypeInfo *table_type = $TableInfo(", compile_type_info(env, args_t), ", ", compile_type_info(env, ret_t), ");\n",
- ret_type_code, "*cached = Table$get_raw(cache, &args, table_type);\n"
+ compile_declaration(Type(PointerType, .pointed=ret_t, .is_optional=true), "cached"), " = Table$get_raw(cache, &args, table_type);\n"
"if (cached) return *cached;\n",
- ret_type_code, " ret = ", name, "$uncached(", all_args, ");\n",
+ compile_declaration(ret_t, "ret"), " = ", name, "$uncached(", all_args, ");\n",
pop_code,
"Table$set(&cache, &args, &ret, table_type);\n"
"return ret;\n"