aboutsummaryrefslogtreecommitdiff
path: root/src/tilde_stmt.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-07-22 07:56:13 +0100
committergingerBill <bill@gingerbill.org>2023-07-22 07:56:13 +0100
commite5f9458905f27b027403a5a0b94cc7762984a08e (patch)
tree04fd5d4c3a0f6aef47bcfe4e025537a388f75734 /src/tilde_stmt.cpp
parentec0a9a5f8a68e03650958acca19f96b3dfd4744e (diff)
Update Tilde to get procedure passing rules
Diffstat (limited to 'src/tilde_stmt.cpp')
-rw-r--r--src/tilde_stmt.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp
index 6aa906288..2cdedbacf 100644
--- a/src/tilde_stmt.cpp
+++ b/src/tilde_stmt.cpp
@@ -252,7 +252,45 @@ gb_internal void cg_addr_store(cgProcedure *p, cgAddr addr, cgValue value) {
} else if (addr.kind == cgAddr_Map) {
GB_PANIC("TODO(bill): cgAddr_Map");
} else if (addr.kind == cgAddr_Context) {
- GB_PANIC("TODO(bill): cgAddr_Context");
+ cgAddr old_addr = cg_find_or_generate_context_ptr(p);
+
+ bool create_new = true;
+ for_array(i, p->context_stack) {
+ cgContextData *ctx_data = &p->context_stack[i];
+ if (ctx_data->ctx.addr.node == old_addr.addr.node) {
+ if (ctx_data->uses > 0) {
+ create_new = true;
+ } else if (p->scope_index > ctx_data->scope_index) {
+ create_new = true;
+ } else {
+ // gb_printf_err("%.*s (curr:%td) (ctx:%td) (uses:%td)\n", LIT(p->name), p->scope_index, ctx_data->scope_index, ctx_data->uses);
+ create_new = false;
+ }
+ break;
+ }
+ }
+
+ cgValue next = {};
+ if (create_new) {
+ cgValue old = cg_addr_load(p, old_addr);
+ cgAddr next_addr = cg_add_local(p, t_context, nullptr, true);
+ cg_addr_store(p, next_addr, old);
+ cg_push_context_onto_stack(p, next_addr);
+ next = next_addr.addr;
+ } else {
+ next = old_addr.addr;
+ }
+
+ if (addr.ctx.sel.index.count > 0) {
+ cgValue lhs = cg_emit_deep_field_gep(p, next, addr.ctx.sel);
+ cgValue rhs = cg_emit_conv(p, value, type_deref(lhs.type));
+ cg_emit_store(p, lhs, rhs);
+ } else {
+ cgValue lhs = next;
+ cgValue rhs = cg_emit_conv(p, value, cg_addr_type(addr));
+ cg_emit_store(p, lhs, rhs);
+ }
+ return;
} else if (addr.kind == cgAddr_SoaVariable) {
GB_PANIC("TODO(bill): cgAddr_SoaVariable");
} else if (addr.kind == cgAddr_Swizzle) {