GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/joels/Current/lispbm/src/extensions/runtime_extensions.c Lines: 110 147 74.8 %
Date: 2025-04-09 11:39:30 Branches: 28 52 53.8 %

Line Branch Exec Source
1
/*
2
    Copyright 2023, 2024 Joel Svensson        svenssonjoel@yahoo.se
3
4
    This program is free software: you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation, either version 3 of the License, or
7
    (at your option) any later version.
8
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13
14
    You should have received a copy of the GNU General Public License
15
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
#include <lbm_memory.h>
19
#include <heap.h>
20
#include <eval_cps.h>
21
#include <extensions.h>
22
#include <lbm_utils.h>
23
#include <lbm_version.h>
24
#include <env.h>
25
26
#ifdef FULL_RTS_LIB
27
static lbm_uint sym_heap_size;
28
static lbm_uint sym_heap_bytes;
29
static lbm_uint sym_num_alloc_cells;
30
static lbm_uint sym_num_alloc_arrays;
31
static lbm_uint sym_num_gc;
32
static lbm_uint sym_num_gc_marked;
33
static lbm_uint sym_num_gc_recovered_cells;
34
static lbm_uint sym_num_gc_recovered_arrays;
35
static lbm_uint sym_num_least_free;
36
static lbm_uint sym_num_last_free;
37
#endif
38
39
28
lbm_value ext_eval_set_quota(lbm_value *args, lbm_uint argn) {
40
28
  LBM_CHECK_ARGN_NUMBER(1);
41
28
  uint32_t q = lbm_dec_as_u32(args[0]);
42
#ifdef LBM_USE_TIME_QUOTA
43
  lbm_set_eval_time_quota(q);
44
#else
45
28
  lbm_set_eval_step_quota(q);
46
#endif
47
28
  return ENC_SYM_TRUE;
48
}
49
50
lbm_value ext_hide_trapped_error(lbm_value *args, lbm_uint argn) {
51
  (void)args;
52
  (void)argn;
53
  lbm_set_hide_trapped_error(true);
54
  return ENC_SYM_TRUE;
55
}
56
57
lbm_value ext_show_trapped_error(lbm_value *args, lbm_uint argn) {
58
  (void)args;
59
  (void)argn;
60
  lbm_set_hide_trapped_error(false);
61
  return ENC_SYM_TRUE;
62
}
63
64
#ifdef FULL_RTS_LIB
65
1064
lbm_value ext_memory_num_free(lbm_value *args, lbm_uint argn) {
66
  (void)args;
67
  (void)argn;
68
1064
  lbm_uint n = lbm_memory_num_free();
69
1064
  return lbm_enc_i((lbm_int)n);
70
}
71
72
112
lbm_value ext_memory_longest_free(lbm_value *args, lbm_uint argn) {
73
  (void)args;
74
  (void)argn;
75
112
  lbm_uint n = lbm_memory_longest_free();
76
112
  return lbm_enc_i((lbm_int)n);
77
}
78
79
28
lbm_value ext_memory_size(lbm_value *args, lbm_uint argn) {
80
  (void)args;
81
  (void)argn;
82
28
  lbm_uint n = lbm_memory_num_words();
83
28
  return lbm_enc_i((lbm_int)n);
84
}
85
86
308
lbm_value ext_memory_word_size(lbm_value *args, lbm_uint argn) {
87
  (void)args;
88
  (void)argn;
89
308
  return lbm_enc_i((lbm_int)sizeof(lbm_uint));
90
}
91
92
28
lbm_value ext_lbm_version(lbm_value *args, lbm_uint argn) {
93
  (void) args;
94
  (void) argn;
95
28
  lbm_value version = lbm_heap_allocate_list_init(3,
96
                                                  lbm_enc_i(LBM_MAJOR_VERSION),
97
                                                  lbm_enc_i(LBM_MINOR_VERSION),
98
                                                  lbm_enc_i(LBM_PATCH_VERSION));
99
28
  return version;
100
}
101
102
252
lbm_value ext_lbm_heap_state(lbm_value *args, lbm_uint argn) {
103
104
252
  lbm_value res = ENC_SYM_TERROR;
105
106
  lbm_heap_state_t hs;
107
252
  lbm_get_heap_state(&hs);
108
109

504
  if (argn == 1 &&
110
252
      lbm_is_symbol(args[0])) {
111
252
    lbm_uint s = lbm_dec_sym(args[0]);
112
252
    if (s == sym_heap_size) {
113
28
      res = lbm_enc_u(hs.heap_size);
114
224
    } else if (s == sym_heap_bytes) {
115
28
      res = lbm_enc_u(hs.heap_bytes);
116
196
    } else if (s == sym_num_alloc_cells) {
117
28
      res = lbm_enc_u(hs.num_alloc);
118
168
    } else if (s == sym_num_alloc_arrays) {
119
      res = lbm_enc_u(hs.num_alloc_arrays);
120
168
    } else if (s == sym_num_gc) {
121
28
      res = lbm_enc_u(hs.gc_num);
122
140
    } else if (s == sym_num_gc_marked) {
123
28
      res = lbm_enc_u(hs.gc_marked);
124
112
    } else if (s == sym_num_gc_recovered_cells) {
125
28
      res = lbm_enc_u(hs.gc_recovered);
126
84
    } else if (s == sym_num_gc_recovered_arrays) {
127
28
      res = lbm_enc_u(hs.gc_recovered_arrays);
128
56
    } else if (s == sym_num_least_free) {
129
28
      res = lbm_enc_u(hs.gc_least_free);
130
28
    } else if (s == sym_num_last_free) {
131
28
      res = lbm_enc_u(hs.gc_last_free);
132
    } else {
133
      res = ENC_SYM_NIL;
134
    }
135
  }
136
252
  return res;
137
}
138
139
672
lbm_value ext_env_get(lbm_value *args, lbm_uint argn) {
140

672
  if (argn == 1 && lbm_is_number(args[0])) {
141
672
    lbm_uint ix = lbm_dec_as_u32(args[0]) & GLOBAL_ENV_MASK;
142
672
    return lbm_get_global_env()[ix];
143
  }
144
  return ENC_SYM_TERROR;
145
}
146
147
lbm_value ext_local_env_get(lbm_value *args, lbm_uint argn) {
148
  (void) args;
149
  (void) argn;
150
  eval_context_t *ctx = lbm_get_current_context();
151
  return ctx->curr_env;
152
}
153
154
56
lbm_value ext_env_set(lbm_value *args, lbm_uint argn) {
155

56
  if (argn == 2 && lbm_is_number(args[0])) {
156
56
    lbm_uint ix = lbm_dec_as_u32(args[0]) & GLOBAL_ENV_MASK;
157
56
    lbm_value *glob_env = lbm_get_global_env();
158
56
    glob_env[ix] = args[1];
159
56
    return ENC_SYM_TRUE;
160
  }
161
  return ENC_SYM_NIL;
162
}
163
164
168
lbm_value ext_set_gc_stack_size(lbm_value *args, lbm_uint argn) {
165
168
  if (argn == 1) {
166
168
    if (lbm_is_number(args[0])) {
167
168
      uint32_t n = lbm_dec_as_u32(args[0]);
168
168
      lbm_uint *new_stack = lbm_malloc(n * sizeof(lbm_uint));
169
168
      if (new_stack) {
170
168
        lbm_free(lbm_heap_state.gc_stack.data);
171
168
        lbm_heap_state.gc_stack.data = new_stack;
172
168
        lbm_heap_state.gc_stack.size = n;
173
168
        lbm_heap_state.gc_stack.sp = 0;  // should already be 0
174
168
        return ENC_SYM_TRUE;
175
      }
176
      return ENC_SYM_MERROR;
177
    }
178
  }
179
  return ENC_SYM_TERROR;
180
}
181
182
280
lbm_value ext_is_64bit(lbm_value *args, lbm_uint argn) {
183
  (void) args;
184
  (void) argn;
185
  #ifndef LBM64
186
280
  return ENC_SYM_NIL;
187
  #else
188
  return ENC_SYM_TRUE;
189
  #endif
190
}
191
192
28
lbm_value ext_symbol_table_size(lbm_uint *args, lbm_uint argn) {
193
  (void) args;
194
  (void) argn;
195
28
  return lbm_enc_u(lbm_get_symbol_table_size());
196
}
197
198
28
lbm_value ext_symbol_table_size_flash(lbm_uint *args, lbm_uint argn) {
199
  (void) args;
200
  (void) argn;
201
28
  return lbm_enc_u(lbm_get_symbol_table_size_flash());
202
}
203
204
28
lbm_value ext_symbol_table_size_names(lbm_uint *args, lbm_uint argn) {
205
  (void) args;
206
  (void) argn;
207
28
  return lbm_enc_u(lbm_get_symbol_table_size_names());
208
}
209
210
28
lbm_value ext_symbol_table_size_names_flash(lbm_uint *args, lbm_uint argn) {
211
  (void) args;
212
  (void) argn;
213
28
  return lbm_enc_u(lbm_get_symbol_table_size_names_flash());
214
}
215
216
138
lbm_value ext_is_always_gc(lbm_uint *args, lbm_uint argn) {
217
  (void) args;
218
  (void) argn;
219
  #ifdef LBM_ALWAYS_GC
220
  return ENC_SYM_TRUE;
221
  #else
222
138
  return ENC_SYM_NIL;
223
  #endif
224
}
225
226
#endif
227
228
#if defined(LBM_USE_EXT_MAILBOX_GET) || defined(FULL_RTS_LIB)
229
230
void find_cid(eval_context_t *ctx, void *arg1, void *arg2) {
231
  lbm_cid id = (lbm_cid)arg1;
232
  if (ctx->id == id) {
233
    *(eval_context_t**)arg2 = ctx;
234
  }
235
}
236
237
238
lbm_value ext_mailbox_get(lbm_uint *args, lbm_uint argn) {
239
  lbm_value res = ENC_SYM_TERROR;
240
  eval_context_t *ctx = NULL;
241
242
  if (argn == 1 && lbm_is_number(args[0])) {
243
    res = ENC_SYM_NIL;
244
    lbm_cid cid = lbm_dec_as_i32(args[0]);
245
    lbm_all_ctxs_iterator(find_cid, (void*)cid, (void*)&ctx);
246
    if (ctx) {
247
      uint32_t num_mail = ctx->num_mail;
248
      lbm_value ls = (lbm_heap_allocate_list(num_mail));
249
      res = ls;
250
      if (lbm_is_ptr(ls)) {
251
        lbm_value curr = ls;
252
        int i = 0;
253
        while (lbm_is_ptr(curr)) {
254
          lbm_set_car(curr, ctx->mailbox[i++]);
255
          curr = lbm_cdr(curr);
256
        }
257
      }
258
    }
259
  }
260
  return res;
261
}
262
#endif
263
264
265
21924
void lbm_runtime_extensions_init(void) {
266
267
#ifdef FULL_RTS_LIB
268
21924
    lbm_add_symbol_const("get-heap-size", &sym_heap_size);
269
21924
    lbm_add_symbol_const("get-heap-bytes", &sym_heap_bytes);
270
21924
    lbm_add_symbol_const("get-num-alloc-cells", &sym_num_alloc_cells);
271
21924
    lbm_add_symbol_const("get-num-alloc-arrays", &sym_num_alloc_arrays);
272
21924
    lbm_add_symbol_const("get-gc-num", &sym_num_gc);
273
21924
    lbm_add_symbol_const("get-gc-num-marked", &sym_num_gc_marked);
274
21924
    lbm_add_symbol_const("get-gc-num-recovered-cells", &sym_num_gc_recovered_cells);
275
21924
    lbm_add_symbol_const("get-gc-num-recovered-arrays", &sym_num_gc_recovered_arrays);
276
21924
    lbm_add_symbol_const("get-gc-num-least-free", &sym_num_least_free);
277
21924
    lbm_add_symbol_const("get-gc-num-last-free", &sym_num_last_free);
278
#endif
279
280
#if defined(LBM_USE_EXT_MAILBOX_GET) || defined(FULL_RTS_LIB)
281
21924
    lbm_add_extension("mailbox-get", ext_mailbox_get);
282
#endif
283
#ifndef FULL_RTS_LIB
284
    lbm_add_extension("set-eval-quota", ext_eval_set_quota);
285
    lbm_add_extension("hide-trapped-error", ext_hide_trapped_error);
286
    lbm_add_extension("show-trapped-error", ext_show_trapped_error);
287
#else
288
21924
    lbm_add_extension("is-always-gc",ext_is_always_gc);
289
21924
    lbm_add_extension("set-eval-quota", ext_eval_set_quota);
290
21924
    lbm_add_extension("hide-trapped-error", ext_hide_trapped_error);
291
21924
    lbm_add_extension("show-trapped-error", ext_show_trapped_error);
292
21924
    lbm_add_extension("mem-num-free", ext_memory_num_free);
293
21924
    lbm_add_extension("mem-longest-free", ext_memory_longest_free);
294
21924
    lbm_add_extension("mem-size", ext_memory_size);
295
21924
    lbm_add_extension("word-size", ext_memory_word_size);
296
21924
    lbm_add_extension("lbm-version", ext_lbm_version);
297
21924
    lbm_add_extension("lbm-heap-state", ext_lbm_heap_state);
298
21924
    lbm_add_extension("env-get", ext_env_get);
299
21924
    lbm_add_extension("env-set", ext_env_set);
300
21924
    lbm_add_extension("local-env-get", ext_local_env_get);
301
21924
    lbm_add_extension("set-gc-stack-size", ext_set_gc_stack_size);
302
21924
    lbm_add_extension("is-64bit", ext_is_64bit);
303
21924
    lbm_add_extension("symtab-size", ext_symbol_table_size);
304
21924
    lbm_add_extension("symtab-size-flash", ext_symbol_table_size_flash);
305
21924
    lbm_add_extension("symtab-size-names", ext_symbol_table_size_names);
306
21924
    lbm_add_extension("symtab-size-names-flash", ext_symbol_table_size_names_flash);
307
#endif
308
21924
}