diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-02-29 13:00:28 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-02-29 13:00:28 -0500 |
| commit | ab17cf75394b0f100bd18668ce637e9aab6ed1e9 (patch) | |
| tree | c7fae004d8849a3ce6ff53abcdbcdf55b7baa5fa /compile.c | |
| parent | 0f34bd8f534d605d6043387ab0b1fc7f621eb489 (diff) | |
Flip COW bit when dereferencing pointers
Diffstat (limited to 'compile.c')
| -rw-r--r-- | compile.c | 11 |
1 files changed, 10 insertions, 1 deletions
@@ -937,7 +937,16 @@ CORD compile(env_t *env, ast_t *ast) auto indexing = Match(ast, Index); type_t *indexed_type = get_type(env, indexing->indexed); if (!indexing->index && indexed_type->tag == PointerType) { - return CORD_all("*(", compile(env, indexing->indexed), ")"); + auto ptr = Match(indexed_type, PointerType); + if (ptr->is_optional) + code_err(ast, "This pointer is potentially null, so it can't be safely dereferenced"); + if (ptr->pointed->tag == ArrayType) { + return CORD_all("({ array_t *$arr = ", compile(env, indexing->indexed), "; $arr->data_refcount = 3; *$arr; })"); + } else if (ptr->pointed->tag == TableType) { + return CORD_all("({ table_t *$t = ", compile(env, indexing->indexed), "; Table_mark_copy_on_write($t); *$t; })"); + } else { + return CORD_all("*(", compile(env, indexing->indexed), ")"); + } } type_t *container_t = value_type(indexed_type); type_t *index_t = get_type(env, indexing->index); |
