Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/internal/1665-arm-d-b6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Migrate buffer and host builtins to the container slot API.
172 changes: 94 additions & 78 deletions src/builtins_buf.c

Large diffs are not rendered by default.

116 changes: 69 additions & 47 deletions src/builtins_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@
rt_error(EK_TYPE, 0, "regex_match requires [string, pattern]");
return make_list(0);
}
if (list_get_borrow(arg, 0)->type != VAL_STR || list_get_borrow(arg, 1)->type != VAL_STR) {
if (list_elem_type(arg, 0) != VAL_STR || list_elem_type(arg, 1) != VAL_STR) {
rt_error(EK_TYPE, 0, "regex_match: string and pattern must be strings");
return make_list(0);
}
const char *str = list_get_borrow(arg, 0)->data.str;
const char *pattern = list_get_borrow(arg, 1)->data.str;
const char *str = list_get_ref(arg, 0)->data.str;
const char *pattern = list_get_ref(arg, 1)->data.str;

regex_t re;
/* #500: an invalid pattern used to return [] — indistinguishable from a
Expand Down Expand Up @@ -100,12 +100,12 @@
rt_error(EK_TYPE, 0, "regex_find requires [string, pattern]");
return make_list(0);
}
if (list_get_borrow(arg, 0)->type != VAL_STR || list_get_borrow(arg, 1)->type != VAL_STR) {
if (list_elem_type(arg, 0) != VAL_STR || list_elem_type(arg, 1) != VAL_STR) {
rt_error(EK_TYPE, 0, "regex_find: string and pattern must be strings");
return make_list(0);
}
const char *str = list_get_borrow(arg, 0)->data.str;
const char *pattern = list_get_borrow(arg, 1)->data.str;
const char *str = list_get_ref(arg, 0)->data.str;
const char *pattern = list_get_ref(arg, 1)->data.str;

regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED) != 0) { /* #500 */
Expand Down Expand Up @@ -143,18 +143,18 @@
* discards it at the CHECK_ERROR seam. */
return make_str("");
}
if (list_get_borrow(arg, 0)->type != VAL_STR ||
list_get_borrow(arg, 1)->type != VAL_STR ||
list_get_borrow(arg, 2)->type != VAL_STR) {
if (list_elem_type(arg, 0) != VAL_STR ||
list_elem_type(arg, 1) != VAL_STR ||
list_elem_type(arg, 2) != VAL_STR) {
rt_error(EK_TYPE, 0, "regex_replace: string, pattern and replacement must be strings");
/* fs:CHANNEL same as above — the unconditional rt_error is the error
* channel; converting to ARG_GUARD would make this site quieter with
* strict OFF, not louder. */
return make_str("");
}
const char *str = list_get_borrow(arg, 0)->data.str;
const char *pattern = list_get_borrow(arg, 1)->data.str;
const char *replacement = list_get_borrow(arg, 2)->data.str;
const char *str = list_get_ref(arg, 0)->data.str;
const char *pattern = list_get_ref(arg, 1)->data.str;
const char *replacement = list_get_ref(arg, 2)->data.str;

regex_t re;
/* #500: an invalid pattern used to return the input unchanged — a silent
Expand Down Expand Up @@ -211,8 +211,10 @@
STRICT_LIST_MAX(arg, 2, "stream_open");
ARG_GUARD(!arg || arg->type != VAL_LIST || arg->data.list.count < 2,
"stream_open", "[path, count]", make_bool(0));
Value *path_val = list_get_borrow(arg, 0);
Value *count_val = list_get_borrow(arg, 1);
EIGS_VIEW(path_val_view);
Value *path_val = list_get_view(arg, 0, &path_val_view);
EIGS_VIEW(count_val_view);
Value *count_val = list_get_view(arg, 1, &count_val_view);
ARG_GUARD(!path_val || path_val->type != VAL_STR || !count_val || count_val->type != VAL_NUM,
"stream_open", "[a string path, a number count]", make_bool(0));
if (eigs_num_arg(count_val, __func__) < 1 ||
Expand Down Expand Up @@ -331,8 +333,7 @@
list_append_owned(list, make_str(entry->d_name));
}
closedir(d);
qsort(list_values_storage(list), list->data.list.count, sizeof(Value*),
ls_entry_cmp);
list_sort(list, ls_entry_cmp);
TRACE_NONDET_RECORD("ls", list);
}

Expand Down Expand Up @@ -397,10 +398,15 @@
if (!arg || arg->type != VAL_LIST || arg->data.list.count < 4)
return make_null();

Value *file_list = list_get_borrow(arg, 0);
Value *topn_val = list_get_borrow(arg, 1);
Value *stream_path_val = list_get_borrow(arg, 2);
Value *vocab_path_val = list_get_borrow(arg, 3);
EIGS_VIEW(file_list_view);

Value *file_list = list_get_view(arg, 0, &file_list_view);
EIGS_VIEW(topn_val_view);
Value *topn_val = list_get_view(arg, 1, &topn_val_view);
EIGS_VIEW(stream_path_val_view);
Value *stream_path_val = list_get_view(arg, 2, &stream_path_val_view);
EIGS_VIEW(vocab_path_val_view);
Value *vocab_path_val = list_get_view(arg, 3, &vocab_path_val_view);

if (!file_list || file_list->type != VAL_LIST) return make_null();
BOOL_REFUSE(topn_val, "build_corpus");
Expand Down Expand Up @@ -437,7 +443,8 @@
* been re-measured on the full corpus.) */
int slot_count = 0;
if (arg->data.list.count >= 6) {
Value *sv = list_get_borrow(arg, 5);
EIGS_VIEW(sv_view);
Value *sv = list_get_view(arg, 5, &sv_view);
double d = 0;
if (eigs_opt_num(sv, &d, "build_corpus")) slot_count = (int)d; /* #1637: a bool raises */
if (g_has_error) return make_null();
Expand Down Expand Up @@ -465,7 +472,8 @@
* high-frequency collision is. Opt-in: 0 leaves the stream byte-identical. */
int int_count = 0;
if (arg->data.list.count >= 7) {
Value *iv = list_get_borrow(arg, 6);
EIGS_VIEW(iv_view);
Value *iv = list_get_view(arg, 6, &iv_view);
double d = 0;
if (eigs_opt_num(iv, &d, "build_corpus")) int_count = (int)d; /* #1637: a bool raises */
if (g_has_error) return make_null();
Expand All @@ -487,7 +495,8 @@
int files_found = 0;

for (int fi = 0; fi < n_files; fi++) {
Value *path_val = list_get_borrow(file_list, fi);
EIGS_VIEW(path_val_view);
Value *path_val = list_get_view(file_list, fi, &path_val_view);
if (!path_val || path_val->type != VAL_STR) { file_tok_counts[fi] = 0; continue; }
const char *path = path_val->data.str;

Expand Down Expand Up @@ -643,7 +652,9 @@
for (int fi = 0; fi < n_files; fi++) {
if (file_tok_counts[fi] <= 0) continue;

Value *path_val = list_get_borrow(file_list, fi);
EIGS_VIEW(path_val_view);

Value *path_val = list_get_view(file_list, fi, &path_val_view);
long fsize = 0;
char *source = read_file_util(path_val->data.str, &fsize);
if (!source) continue;
Expand Down Expand Up @@ -752,7 +763,8 @@
* Sorted by count descending. Enables exact coverage(top_n) curves
* without re-running the full corpus build. */
if (arg->data.list.count >= 5) {
Value *idents_path_val = list_get_borrow(arg, 4);
EIGS_VIEW(idents_path_val_view);
Value *idents_path_val = list_get_view(arg, 4, &idents_path_val_view);
if (idents_path_val && idents_path_val->type == VAL_STR && n_idents > 0) {
/* Build index array, sort descending by count via simple sort */
int *order = xmalloc_array(n_idents, sizeof(int));
Expand Down Expand Up @@ -1003,8 +1015,10 @@
STRICT_LIST_MAX(arg, 2, "rename");
ARG_GUARD(!arg || arg->type != VAL_LIST || arg->data.list.count < 2,
"rename", "[old_path, new_path]", make_bool(0));
Value *from = list_get_borrow(arg, 0);
Value *to = list_get_borrow(arg, 1);
EIGS_VIEW(from_view);
Value *from = list_get_view(arg, 0, &from_view);
EIGS_VIEW(to_view);
Value *to = list_get_view(arg, 1, &to_view);
ARG_GUARD(!from || from->type != VAL_STR || !to || to->type != VAL_STR,
"rename", "two string paths", make_bool(0));
return make_bool(rename(from->data.str, to->data.str) == 0);
Expand Down Expand Up @@ -1085,9 +1099,10 @@
"read_bytes_buf of path, or read_bytes_buf of [path, max_bytes]");
return make_null();
}
path = list_get_borrow(arg, 0);
path = list_get_ref(arg, 0);
if (arg->data.list.count >= 2) {
Value *mv = list_get_borrow(arg, 1);
EIGS_VIEW(mv_view);
Value *mv = list_get_view(arg, 1, &mv_view);
if (!mv || mv->type != VAL_NUM) {
rt_error(EK_VALUE, 0, "read_bytes_buf: max_bytes must be a number");
return make_null();
Expand Down Expand Up @@ -1212,8 +1227,10 @@
STRICT_LIST_MAX(arg, 2, "write_text");
ARG_GUARD(!arg || arg->type != VAL_LIST || arg->data.list.count < 2,
"write_text", "[path, text]", make_bool(0));
Value *path_val = list_get_borrow(arg, 0);
Value *text_val = list_get_borrow(arg, 1);
EIGS_VIEW(path_val_view);
Value *path_val = list_get_view(arg, 0, &path_val_view);
EIGS_VIEW(text_val_view);
Value *text_val = list_get_view(arg, 1, &text_val_view);
ARG_GUARD(!path_val || path_val->type != VAL_STR ||
!text_val || text_val->type != VAL_STR,
"write_text", "two strings", make_bool(0));
Expand Down Expand Up @@ -1270,9 +1287,9 @@
double timeout_sec = -1;
Value *cmd_list = arg;
if (arg->data.list.count == 2
&& list_get_borrow(arg, 0) && list_get_borrow(arg, 0)->type == VAL_LIST
&& list_get_borrow(arg, 1) && list_get_borrow(arg, 1)->type == VAL_NUM) {
cmd_list = list_get_borrow(arg, 0);
&& list_elem_type(arg, 0) == VAL_LIST
&& list_elem_type(arg, 1) == VAL_NUM) {
cmd_list = list_get_ref(arg, 0);
Comment thread
InauguralPhysicist marked this conversation as resolved.
Dismissed
timeout_sec = eigs_list_num(arg, 1, __func__);
ARG_GUARD(cmd_list->data.list.count < 1,
"exec_capture", "a non-empty command list", exec_capture_result(-1, ""));
Expand All @@ -1286,7 +1303,8 @@
* outcome, not an argument the caller got wrong. */
if (!argv) return exec_capture_result(-1, "");
for (int i = 0; i < total; i++) {
Value *v = list_get_borrow(cmd_list, i);
EIGS_VIEW(v_view);
Value *v = list_get_view(cmd_list, i, &v_view);
if (!v || v->type != VAL_STR) {
free(argv);
ARG_GUARD(1, "exec_capture", "a list of strings", exec_capture_result(-1, ""));
Expand Down Expand Up @@ -1417,8 +1435,10 @@
if (replay_blocks("proc_read_buf")) return make_null();
if (!arg || arg->type != VAL_LIST || arg->data.list.count != 2)
return make_null();
Value *fd_v = list_get_borrow(arg, 0);
Value *max_v = list_get_borrow(arg, 1);
EIGS_VIEW(fd_v_view);
Value *fd_v = list_get_view(arg, 0, &fd_v_view);
EIGS_VIEW(max_v_view);
Value *max_v = list_get_view(arg, 1, &max_v_view);
if (!fd_v || fd_v->type != VAL_NUM || !max_v || max_v->type != VAL_NUM)
return make_null();
int fd = (int)eigs_num_arg(fd_v, __func__);
Expand Down Expand Up @@ -1481,25 +1501,26 @@
STRICT_LIST_MAX(arg, 3, "write_bytes");
ARG_GUARD(!arg || arg->type != VAL_LIST || arg->data.list.count < 2,
"write_bytes", "[path, data] (optionally [path, data, append])", make_num(0));
Value *path_val = list_get_borrow(arg, 0);
Value *data = list_get_borrow(arg, 1);
EIGS_VIEW(path_val_view);
Value *path_val = list_get_view(arg, 0, &path_val_view);
EIGS_VIEW(data_view);
Value *data = list_get_view(arg, 1, &data_view);
ARG_GUARD(!path_val || path_val->type != VAL_STR,
"write_bytes", "a string path as its first argument", make_num(0));
/* #1637: append is a flag -- a bool, or the older nonzero number. Any
* other value raises rather than silently meaning "truncate". */
int append = 0;
if (arg->data.list.count >= 3 && list_get_borrow(arg, 2)) {
Value *fl = list_get_borrow(arg, 2);
if (arg->data.list.count >= 3) {
EIGS_VIEW(fl_view);
Value *fl = list_get_view(arg, 2, &fl_view);
if (fl->type == VAL_BOOL) append = fl->data.boolean;
else if (fl->type != VAL_NULL) append = (eigs_num_arg(fl, "write_bytes") != 0.0);
if (g_has_error) return make_num(0);
}

int n = 0;
Value **items = NULL;
if (data && data->type == VAL_LIST) {
n = data->data.list.count;
items = list_values_storage(data);
} else if (data && data->type == VAL_BUFFER) {
n = data->data.buffer.count;
} else {
Expand All @@ -1517,14 +1538,15 @@
* two zero bytes and reported success. Same class as join/str_replace
* — no stand-in return, so invisible to the classifier. The free()
* matters: STRICT_REQUIRE returns, and `out` is already allocated. */
if (items && (!items[i] || items[i]->type != VAL_NUM)
&& (g_strict || (items[i] && items[i]->type == VAL_BOOL))) { /* #1637: a bool in every mode */
if (data->type == VAL_LIST && list_elem_type(data, i) != VAL_NUM
&& (g_strict || list_elem_type(data, i) == VAL_BOOL)) { /* #1637: a bool in every mode */
free(out);
rt_error(EK_TYPE, 0, "write_bytes: expected every element to be a number");
return make_null();
}
double dv = items ? (items[i] && items[i]->type == VAL_NUM ? eigs_num_arg(items[i], __func__) : 0.0)
: buffer_read_num(data, i);
double dv = data->type == VAL_LIST
? eigs_slot_elem_num(list_slot(data, i), __func__)
: buffer_read_num(data, i);
if (g_has_error) { free(out); return make_null(); }
out[i] = finite_num_to_byte(dv);
}
Expand Down
2 changes: 2 additions & 0 deletions tools/container_migrated_files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ src/builtins_tensor.c
src/model_infer.c
src/model_train.c
src/model_io.c
src/builtins_buf.c
src/builtins_host.c
2 changes: 1 addition & 1 deletion tools/strict_shape_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def functions(sources):
# Deliberately remove annotations before candidate discovery.
code = re.sub(r'STRICT_LIST_MAX\([^;]*;', '', code)
# data.list or its #1665 container.h accessors (list_get_*/list_iter_*/...)
direct = bool(re.search(r'\bVAL_LIST\b|data\.list|\blist_(?:get|set|iter|values)_\w*\(|\bARG_COUNT\b|\bARG_AT\b', code))
direct = bool(re.search(r'\bVAL_LIST\b|data\.list|\blist_(?:get|set|iter|values)_\w*\(|\blist_sort\(|\bARG_COUNT\b|\bARG_AT\b', code))
direct |= 'arg->data.dict' in code and bool(re.search(r'\bmake_list\s*\(', code))
helpers = set()
for call in re.finditer(r'\b([A-Za-z_]\w*)\s*\(', code):
Expand Down
30 changes: 15 additions & 15 deletions tools/strict_shape_contracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,11 @@
],
"disposition": "exempt",
"body_sha256": [
"3d0d2c08324818d4ac65fe020224d685a9aac0e415d7bb69f54113b24a90aba0"
"9800ff3dcb6c1929c5b9326884f3d1a9cf99668756e25da259ba7dc962e198ee"
],
"source_sha256": {
"builtin_buf_from_list": [
"3d0d2c08324818d4ac65fe020224d685a9aac0e415d7bb69f54113b24a90aba0"
"9800ff3dcb6c1929c5b9326884f3d1a9cf99668756e25da259ba7dc962e198ee"
]
}
},
Expand Down Expand Up @@ -503,11 +503,11 @@
],
"disposition": "exempt",
"body_sha256": [
"0f2463d9f7d4223393269796d4688a5d8fa708244de3f974f0e2f62c8cb0b540"
"2fd695baaa8e9743399e40a9483778ca9c3bda2b1d297f012b6b844fc5806103"
],
"source_sha256": {
"builtin_buffer": [
"0f2463d9f7d4223393269796d4688a5d8fa708244de3f974f0e2f62c8cb0b540"
"2fd695baaa8e9743399e40a9483778ca9c3bda2b1d297f012b6b844fc5806103"
],
"eigs_list_num": [
"25755c9b1f519fb0447e2d648dc0272419914db805f9249954cd2e146b48a3bc"
Expand Down Expand Up @@ -772,11 +772,11 @@
],
"disposition": "exempt",
"body_sha256": [
"268d0eea61701a8101ef750b078302f77890f8baf08b211aebb51c75ce87293d"
"167f0efe94c146d6daa77ed91fd3ef73368fcfacfd373a2ee91ba6f5bccc9e0d"
],
"source_sha256": {
"builtin_exec_capture": [
"268d0eea61701a8101ef750b078302f77890f8baf08b211aebb51c75ce87293d"
"167f0efe94c146d6daa77ed91fd3ef73368fcfacfd373a2ee91ba6f5bccc9e0d"
],
"eigs_list_num": [
"25755c9b1f519fb0447e2d648dc0272419914db805f9249954cd2e146b48a3bc"
Expand Down Expand Up @@ -807,11 +807,11 @@
],
"disposition": "exempt",
"body_sha256": [
"1872757a55392e54f959bd7659f1784ef0af3a43f4a6a8fc964c82cb475caea7"
"37cace163aae93897420ade0a6cb5ad56c3c7a3dfa43d351c93e299a1f4e3d57"
],
"source_sha256": {
"builtin_f64_from_bytes": [
"1872757a55392e54f959bd7659f1784ef0af3a43f4a6a8fc964c82cb475caea7"
"37cace163aae93897420ade0a6cb5ad56c3c7a3dfa43d351c93e299a1f4e3d57"
]
}
},
Expand Down Expand Up @@ -1151,10 +1151,10 @@
"d89562220316e85c2ed110b250eee934769205aab21a2f3bc76a9804aa171060"
],
"strict_numeric_byte_list": [
"79f5f890f930f0eec678dc9851a7656462c94eeffc5468bccf7ee536988f68e3"
"c44801e4253c003e32d5daa43ec63454efc8faa0b13403ccd8f6e7b7bbe92b7e"
],
"zlib_bytes_arg": [
"11bf36d12e06d6f30fe673a5868e7f5db8888e3fe70ee45c0bc34df81acf2c63"
"482e756d657040d3c334c618e569d1824ed17c26f49a826b564aec1b0e86e5d3"
],
"zlib_inflate_impl": [
"a54f1d8a2b596ca7c363f20303516358bf5992479e5aadc7ea6f2536e2089914"
Expand Down Expand Up @@ -1358,11 +1358,11 @@
],
"disposition": "exempt",
"body_sha256": [
"94c3dd22d5e23b8370953c33ec40911a2bdc883501c741e689efe1defbed8b1f"
"9f31a265aef07d6971eb0c4eeab2f799f458d5fdd5ff977e0ab84b8b9d61b043"
],
"source_sha256": {
"builtin_ls": [
"94c3dd22d5e23b8370953c33ec40911a2bdc883501c741e689efe1defbed8b1f"
"9f31a265aef07d6971eb0c4eeab2f799f458d5fdd5ff977e0ab84b8b9d61b043"
]
}
},
Expand Down Expand Up @@ -2146,14 +2146,14 @@
],
"disposition": "exempt",
"body_sha256": [
"90f545588091252200b754a2ff1764b111a8d0010212b8c10d49bb0064e1bb1f"
"aff6b5f42bc298bbd9e89a1b3b4e6869e6675974152841f17a47bee7a7cde312"
],
"source_sha256": {
"builtin_str_from_bytes": [
"90f545588091252200b754a2ff1764b111a8d0010212b8c10d49bb0064e1bb1f"
"aff6b5f42bc298bbd9e89a1b3b4e6869e6675974152841f17a47bee7a7cde312"
],
"strict_numeric_byte_list": [
"79f5f890f930f0eec678dc9851a7656462c94eeffc5468bccf7ee536988f68e3"
"c44801e4253c003e32d5daa43ec63454efc8faa0b13403ccd8f6e7b7bbe92b7e"
]
}
},
Expand Down
Loading