Skip to content

Commit 60970cc

Browse files
committed
fix(codegen): prevent a huge class of name collisions
1 parent 7c504f1 commit 60970cc

12 files changed

Lines changed: 311 additions & 137 deletions

File tree

docs/overview/16-ffi-c-interop.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,35 @@ Extern structs without an init function cannot be default-constructed:
127127
f: io::File // error because io::File has no extern init function
128128
```
129129

130-
### 16.4 Native build requirements
130+
### 16.4 Generated C names and identifier restrictions
131+
132+
Jik reserves identifiers beginning with `jik_`, `Jik`, and `JIK`. Do not use
133+
these prefixes for functions, types, globals, locals, fields, module aliases,
134+
or other Jik identifiers.
135+
136+
Jik emits local variables and struct fields using their source spelling. To
137+
keep the generated C valid, names reserved by the C backend are also rejected
138+
in those positions. This includes C keywords, implementation-reserved names
139+
such as `__name` and `_Name`, and common names from the C headers included by
140+
Jik, such as `size_t`, `FILE`, `EOF`, and `NULL`.
141+
142+
Generated C names are implementation details, not a stable C API. In
143+
particular, the compiler currently uses these namespaces:
144+
145+
```text
146+
jik_src_* symbols derived from Jik source declarations
147+
jik_vec_* generated vector types and helpers
148+
jik_dict_* generated dictionary types and helpers
149+
jik_opt_* generated option types and helpers
150+
jik_* compiler and runtime helpers
151+
Jik* runtime C types
152+
```
153+
154+
Embedded C is passed through unchanged and may introduce its own names or C
155+
macros. It must therefore avoid collisions with Jik-generated names and
156+
follow the normal C rules itself.
157+
158+
### 16.5 Native build requirements
131159

132160
An FFI module can declare the include paths, library paths, libraries, and runtime files needed to
133161
build programs that import it:

jiklib/bytes.jik

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,14 @@ extern func jik_impl_bytes_to_bytes as
181181
typedef struct jik_impl_bytes_Bytes {
182182
uint8_t *data;
183183
size_t size;
184-
JikRegion *region;
184+
JikRegion *jik_region;
185185
} jik_impl_bytes_Bytes;
186186

187187
typedef struct jik_impl_bytes_ByteBuf {
188188
uint8_t *data;
189189
size_t size;
190190
size_t capacity;
191-
JikRegion *region;
191+
JikRegion *jik_region;
192192
} jik_impl_bytes_ByteBuf;
193193

194194
static int32_t
@@ -203,7 +203,7 @@ jik_impl_bytes_alloc_bytes(uint8_t *data, size_t size, JikRegion *a)
203203
jik_impl_bytes_Bytes *bytes = jik_region_alloc(a, sizeof(jik_impl_bytes_Bytes));
204204
bytes->data = data;
205205
bytes->size = size;
206-
bytes->region = a;
206+
bytes->jik_region = a;
207207
return bytes;
208208
}
209209

@@ -229,7 +229,7 @@ jik_impl_bytes_string_from_raw(uint8_t *data, size_t size, JikRegion *a)
229229
s->data[size] = '\0';
230230
s->size = size;
231231
s->capacity = size;
232-
s->region = a;
232+
s->jik_region = a;
233233
return s;
234234
}
235235

@@ -248,7 +248,7 @@ jik_impl_bytes_buf_reserve(jik_impl_bytes_ByteBuf *buf, size_t needed)
248248
new_cap *= 2;
249249
}
250250

251-
uint8_t *new_data = jik_region_alloc(buf->region, new_cap);
251+
uint8_t *new_data = jik_region_alloc(buf->jik_region, new_cap);
252252
if (buf->data && buf->size > 0) {
253253
memcpy(new_data, buf->data, buf->size);
254254
}
@@ -355,7 +355,7 @@ jik_impl_bytes_buf_new(JikRegion *a)
355355
buf->data = jik_region_alloc(a, 16);
356356
buf->size = 0;
357357
buf->capacity = 16;
358-
buf->region = a;
358+
buf->jik_region = a;
359359
return buf;
360360
}
361361

jiklib/io.jik

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ typedef struct jik_impl_io_File {
9393
FILE *file;
9494
bool valid;
9595
JikString *mode;
96-
JikRegion *region;
96+
JikRegion *jik_region;
9797
} jik_impl_io_File;
9898

9999
static bool
@@ -112,7 +112,7 @@ jik_impl_io_open(JikString *filepath, JikString *mode, JikRegion *a, JikError *e
112112
fh->file = NULL;
113113
fh->mode = jik_string_new(mode->data, a);
114114
fh->valid = false;
115-
fh->region = a;
115+
fh->jik_region = a;
116116
return fh;
117117
}
118118
jik_impl_io_File *fh = jik_region_alloc(a, sizeof(jik_impl_io_File));
@@ -122,7 +122,7 @@ jik_impl_io_open(JikString *filepath, JikString *mode, JikRegion *a, JikError *e
122122
if (!fh->valid) {
123123
jik_error_set(e, 1, "io::open: could not open file");
124124
}
125-
fh->region = a;
125+
fh->jik_region = a;
126126
return fh;
127127
}
128128

jiklib/process.jik

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ extern func jik_impl_process_result_err as
6969

7070
@embed{C_END}
7171

72-
struct vec_JikString;
73-
JikString *vec_JikString_get(struct vec_JikString *v, size_t idx, char *dbg_info);
74-
size_t vec_JikString_size(struct vec_JikString *v, char *dbg_info);
72+
struct jik_vec_JikString;
73+
JikString *jik_vec_JikString_get(struct jik_vec_JikString *v, size_t idx, char *dbg_info);
74+
size_t jik_vec_JikString_size(struct jik_vec_JikString *v, char *dbg_info);
7575
struct jik_impl_bytes_Bytes;
7676
struct jik_impl_bytes_Bytes *
7777
jik_impl_bytes_from_raw_copy(uint8_t *data, size_t size, JikRegion *a);
@@ -234,14 +234,14 @@ jik_impl_process_append_windows_arg(JikCharBuffer *b, const char *arg, JikRegion
234234

235235
static char *
236236
jik_impl_process_build_windows_command_line(
237-
JikString *program, struct vec_JikString *args, JikRegion *r)
237+
JikString *program, struct jik_vec_JikString *args, JikRegion *r)
238238
{
239239
JikCharBuffer *b = jik_char_buffer_new("", r);
240240
jik_impl_process_append_windows_arg(b, program->data, r);
241241

242-
size_t n = vec_JikString_size(args, "process::run args");
242+
size_t n = jik_vec_JikString_size(args, "process::run args");
243243
for (size_t i = 0; i < n; i++) {
244-
JikString *arg = vec_JikString_get(args, i, "process::run args");
244+
JikString *arg = jik_vec_JikString_get(args, i, "process::run args");
245245
jik_char_buffer_append_char(b, ' ', r);
246246
jik_impl_process_append_windows_arg(b, arg->data, r);
247247
}
@@ -250,7 +250,7 @@ jik_impl_process_build_windows_command_line(
250250
}
251251

252252
int32_t
253-
jik_impl_process_run(JikString *program, struct vec_JikString *args, JikError *e)
253+
jik_impl_process_run(JikString *program, struct jik_vec_JikString *args, JikError *e)
254254
{
255255
if (program->data[0] == '\0') {
256256
jik_impl_process_set_error(e, "process::run: invalid program");
@@ -358,7 +358,7 @@ jik_impl_process_create_pipe(HANDLE *read_handle, HANDLE *write_handle)
358358
}
359359

360360
jik_impl_process_Result *
361-
jik_impl_process_capture_raw(JikString *program, struct vec_JikString *args, JikRegion *out_region, JikError *e)
361+
jik_impl_process_capture_raw(JikString *program, struct jik_vec_JikString *args, JikRegion *out_region, JikError *e)
362362
{
363363
if (program->data[0] == '\0') {
364364
jik_impl_process_set_error(e, "process::capture: invalid program");
@@ -501,17 +501,17 @@ jik_impl_process_close_if_open(int fd)
501501
}
502502

503503
static char **
504-
jik_impl_process_build_argv(JikString *program, struct vec_JikString *args)
504+
jik_impl_process_build_argv(JikString *program, struct jik_vec_JikString *args)
505505
{
506-
size_t n = vec_JikString_size(args, "process::run args");
506+
size_t n = jik_vec_JikString_size(args, "process::run args");
507507
char **argv = malloc((n + 2) * sizeof(char *));
508508
if (!argv) {
509509
return NULL;
510510
}
511511

512512
argv[0] = program->data;
513513
for (size_t i = 0; i < n; i++) {
514-
JikString *arg = vec_JikString_get(args, i, "process::run args");
514+
JikString *arg = jik_vec_JikString_get(args, i, "process::run args");
515515
argv[i + 1] = arg->data;
516516
}
517517
argv[n + 1] = NULL;
@@ -531,7 +531,7 @@ jik_impl_process_exit_code_from_status(int status)
531531
}
532532

533533
int32_t
534-
jik_impl_process_run(JikString *program, struct vec_JikString *args, JikError *e)
534+
jik_impl_process_run(JikString *program, struct jik_vec_JikString *args, JikError *e)
535535
{
536536
if (program->data[0] == '\0') {
537537
jik_impl_process_set_error(e, "process::run: invalid program");
@@ -687,7 +687,7 @@ jik_impl_process_drain_pipes(int stdout_fd,
687687
}
688688

689689
jik_impl_process_Result *
690-
jik_impl_process_capture_raw(JikString *program, struct vec_JikString *args, JikRegion *out_region, JikError *e)
690+
jik_impl_process_capture_raw(JikString *program, struct jik_vec_JikString *args, JikRegion *out_region, JikError *e)
691691
{
692692
if (program->data[0] == '\0') {
693693
jik_impl_process_set_error(e, "process::capture: invalid program");

jiklib/strbuf.jik

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ typedef struct jik_StrBuf {
8585
char *data;
8686
size_t size;
8787
size_t capacity;
88-
JikRegion *region;
88+
JikRegion *jik_region;
8989
} jik_StrBuf;
9090

9191
jik_StrBuf *
@@ -98,7 +98,7 @@ jik_strbuf_new(JikString *from, JikRegion *a)
9898
sb->data[n] = '\0';
9999
sb->size = n;
100100
sb->capacity = n;
101-
sb->region = a;
101+
sb->jik_region = a;
102102
return sb;
103103
}
104104

@@ -116,7 +116,7 @@ jik_strbuf_append(jik_StrBuf *sb, JikString *s)
116116
new_cap *= 2;
117117
}
118118

119-
char *new_data = jik_region_alloc(sb->region, new_cap + 1);
119+
char *new_data = jik_region_alloc(sb->jik_region, new_cap + 1);
120120
if (sb->data && sb->size) {
121121
memcpy(new_data, sb->data, sb->size);
122122
}
@@ -137,7 +137,7 @@ jik_strbuf_append_char(jik_StrBuf *sb, char ch)
137137
while (new_cap + 1 < req) {
138138
new_cap *= 2;
139139
}
140-
char *new_data = jik_region_alloc(sb->region, new_cap + 1);
140+
char *new_data = jik_region_alloc(sb->jik_region, new_cap + 1);
141141
if (sb->data && sb->size) {
142142
memcpy(new_data, sb->data, sb->size);
143143
}

0 commit comments

Comments
 (0)