diff options
-rw-r--r-- | HACKING | 96 | ||||
-rw-r--r-- | buf.c | 5 | ||||
-rwxr-xr-x | configure | 5 | ||||
-rw-r--r-- | eval.c | 6 | ||||
-rw-r--r-- | ffi.c | 10 | ||||
-rw-r--r-- | gc.c | 18 | ||||
-rw-r--r-- | hash.c | 3 | ||||
-rw-r--r-- | lib.c | 79 | ||||
-rw-r--r-- | linenoise/linenoise.c | 3 | ||||
-rw-r--r-- | parser.c | 5 | ||||
-rw-r--r-- | regex.c | 6 | ||||
-rw-r--r-- | signal.c | 2 | ||||
-rw-r--r-- | stream.c | 4 | ||||
-rw-r--r-- | struct.c | 18 | ||||
-rw-r--r-- | sysif.c | 22 | ||||
-rw-r--r-- | time.c | 6 | ||||
-rw-r--r-- | tree.c | 44 | ||||
-rw-r--r-- | unwind.c | 3 | ||||
-rw-r--r-- | unwind.h | 17 | ||||
-rw-r--r-- | vm.c | 14 |
20 files changed, 215 insertions, 151 deletions
@@ -8,40 +8,40 @@ SECTION LINE 0. Overview 47 1. Coding Practice 54 -1.2 Program File Structure 77 -1.3 Style 91 -1.3 Error Handling 153 -1.4 I/O 166 -1.5 Type Safety 176 -1.6 Regression 218 - -2. Dynamic Types 227 -2.1 Two Kinds of Values 234 -2.1 Pointer Bitfield 245 -2.2 Heap Objects 268 -2.3 The COBJ type 288 -2.4 Strings 305 -2.4.1 Encapsulated C Strings 320 -2.4.2 Representation Hacks for 2-byte wchar_t 364 - -3. Garbage Collection 423 -3.1 Root Pointers 441 -3.2 GC-safe Code 464 -3.2.1 Rule One: Full Initialization 490 -3.2.2 Rule Two: Make it Reachable 519 -3.3 Weak Reference Support 707 -3.4 Finalization 750 -3.5 Generational GC 774 -3.5.2 Representation of Generations 783 -3.5.3 Basic Algorithm 819 -3.5.4 Handling Backpointers 854 -3.5.5 Generational GC and Finalization 932 - -4. Debugging 961 -4.2. Debugging the Yacc-generated Parser 1092 -4.3. Debugging GC Issues 1105 -4.4 Object Breakpoint 1128 -4.5 Valgrind: Your Friend 1147 +1.2 Program File Structure 95 +1.3 Style 109 +1.3 Error Handling 171 +1.4 I/O 184 +1.5 Type Safety 194 +1.6 Regression 236 + +2. Dynamic Types 245 +2.1 Two Kinds of Values 252 +2.1 Pointer Bitfield 263 +2.2 Heap Objects 286 +2.3 The COBJ type 306 +2.4 Strings 323 +2.4.1 Encapsulated C Strings 338 +2.4.2 Representation Hacks for 2-byte wchar_t 382 + +3. Garbage Collection 441 +3.1 Root Pointers 459 +3.2 GC-safe Code 482 +3.2.1 Rule One: Full Initialization 508 +3.2.2 Rule Two: Make it Reachable 537 +3.3 Weak Reference Support 725 +3.4 Finalization 768 +3.5 Generational GC 792 +3.5.2 Representation of Generations 801 +3.5.3 Basic Algorithm 837 +3.5.4 Handling Backpointers 872 +3.5.5 Generational GC and Finalization 950 + +4. Debugging 979 +4.2. Debugging the Yacc-generated Parser 1110 +4.3. Debugging GC Issues 1123 +4.4 Object Breakpoint 1146 +4.5 Valgrind: Your Friend 1165 0. Overview @@ -56,11 +56,29 @@ provide rationale and make coding recommendations. 1.1 Language Txr is written in a language that consists of the common dialect between C90 -and C++98. The code can be built with either the GNU C compiler or the GNU C++ -compiler. Use is made of some Unix functions from before Unix95, which are -requested by means of -D_XOPEN_SOURCE (POSIX.1, POSIX.2, X/Open Portability -Guide 4). Also, the <wchar.h> header is used, which was introduced by a 1995 -addendum to the C language, so it may be said that the actual C dialect is C95. +and C++98, with some GCC extensions, such as: + +- initializing structure members with values not computable at load-time +- converting between object and function pointers +- certain extensions detected by the configure script as working, such + as the long long type +- bitfields of an enum type rather than int. + +The code can be built with either the GNU C compiler or the GNU C++ +compiler. + +Use is made of numerous library functions which are detected by the configure +script without regard for dialect. For instance, some C99 mathematics functions +are used, if available, as well as numerous POSIX functions. Effectively, these +can be regarded as extensions to the C90 language, since they are revealed in +the headers and library linkage. + +The <inttypes.h> header isn't used, though there is a reference to it in +the Flex-generated scanner, active only if that is compiled in C99 mode. + +The <wchar.h> header is used, which was introduced by a 1995 addendum to the C +language, so it may be said that the actual C dialect is C95 with some +extensions. In coding new features or fixing bugs, care must be taken to preserve this. Code must continue to compile as C and C++, and not increase the portability @@ -351,10 +351,11 @@ val replace_buf(val buf, val items, val from, val to) memmove(buf->b.data + c_num(from, self), items->b.data, c_num(len_it, self)); } else { seq_iter_t item_iter; - seq_iter_init(self, &item_iter, items); cnum f = c_num(from, self); cnum t = c_num(to, self); + seq_iter_init(self, &item_iter, items); + for (; f != t; f++) { val item = seq_geti(&item_iter); buf_put_uchar(buf, num(f), item); @@ -367,7 +368,7 @@ val replace_buf(val buf, val items, val from, val to) val buf_list(val list) { - val self = lit("buf-list");; + val self = lit("buf-list"); val len = length(list); val buf = make_buf(zero, zero, len); seq_iter_t iter; @@ -167,8 +167,8 @@ nm='$(cross)$(tool_prefix)nm' opt_flags='-O2 -fno-stack-protector' lang_flags='-D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200112 -D_GNU_SOURCE' diag_flags="-Wall -Wextra -Werror=implicit-function-declaration \ - -Werror=missing-prototypes -Werror=strict-prototypes \ - -Werror=old-style-definition" + -Werror=missing-prototypes -Werror=strict-prototypes -Werror=vla \ + -Werror=old-style-definition -Werror=declaration-after-statement" debug_flags=-g debug_only_flags=-DTXR_DEBUG debug_also= @@ -810,6 +810,7 @@ if [ $cplusplus ] ; then diag_flags='' for flag in "$@" ; do case $flag in + *=declaration-after-statement | \ *=implicit-function-declaration | \ *=missing-prototypes | \ *=old-style-* | \ @@ -2670,11 +2670,12 @@ static val op_dohash(val form, val env) val valvar = cons(valsym, nil); val new_env = make_env(cons(keyvar, cons(valvar, nil)), nil, env); val cell; + val result = nil; struct hash_iter hi; hash_iter_init(&hi, eval(hashform, env, hashform), op); - uw_block_begin (nil, result); + uw_block_beg (nil, result); while ((cell = hash_iter_next(&hi)) != nil) { /* These assignments are gc-safe, because keyvar and valvar @@ -3125,8 +3126,9 @@ static val op_upenv(val form, val env) static val op_load_time_lit(val form, val env) { - (void) env; val args = cdr(form); + (void) env; + if (car(args)) { return cadr(args); } else { @@ -509,17 +509,17 @@ static val ffi_void_get(struct txr_ffi_type *tft, mem_t *src, val self) static void ffi_simple_release(struct txr_ffi_type *tft, val obj, mem_t *dst, val self) { + mem_t **loc = coerce(mem_t **, dst); (void) tft; (void) obj; (void) self; - mem_t **loc = coerce(mem_t **, dst); free(*loc); *loc = 0; } #if __i386__ || __x86_64__ || __PPC64__ || __ARM_FEATURE_UNALIGNED -#define align_sw_get(type, src) +#define align_sw_get(type, src) enum { dummy ## __LINE__ } #define align_sw_end #define align_sw_put_end #define align_sw_put(type, dst, expr) (expr) @@ -531,7 +531,7 @@ static void ffi_simple_release(struct txr_ffi_type *tft, val obj, const size_t sz = sizeof (type); \ mem_t *src_prev = src; \ mem_t *buf = al ? src : convert(mem_t *, alloca(sz)); \ - mem_t *src = al ? buf : (memcpy(buf, src_prev, sz), buf); + mem_t *src = al ? buf : (memcpy(buf, src_prev, sz), buf) #define align_sw_end \ } @@ -557,8 +557,8 @@ static void ffi_simple_release(struct txr_ffi_type *tft, val obj, #if HAVE_I8 static void ffi_i8_put(struct txr_ffi_type *tft, val n, mem_t *dst, val self) { - (void) tft; i8_t v = c_i8(n, self); + (void) tft; *coerce(i8_t *, dst) = v; } @@ -571,8 +571,8 @@ static val ffi_i8_get(struct txr_ffi_type *tft, mem_t *src, val self) static void ffi_u8_put(struct txr_ffi_type *tft, val n, mem_t *dst, val self) { - (void) tft; u8_t v = c_u8(n, self); + (void) tft; *coerce(u8_t *, dst) = v; } @@ -914,14 +914,16 @@ void gc_init(val *stack_bottom) gc_stack_bottom = stack_bottom; gc_stack_limit = gc_stack_bottom - DFL_STACK_LIMIT / sizeof (val); #if HAVE_RLIMIT - struct rlimit rl; - if (getrlimit(RLIMIT_STACK, &rl) == 0) { - rlim_t lim = rl.rlim_cur; - if (lim != RLIM_INFINITY) { - ptrdiff_t delta = (lim >= MIN_STACK_LIMIT - ? (lim - lim / 16) - : MIN_STACK_LIMIT) / sizeof (val); - gc_stack_limit = gc_stack_bottom - delta; + { + struct rlimit rl; + if (getrlimit(RLIMIT_STACK, &rl) == 0) { + rlim_t lim = rl.rlim_cur; + if (lim != RLIM_INFINITY) { + ptrdiff_t delta = (lim >= MIN_STACK_LIMIT + ? (lim - lim / 16) + : MIN_STACK_LIMIT) / sizeof (val); + gc_stack_limit = gc_stack_bottom - delta; + } } } #endif @@ -2096,6 +2096,8 @@ void hash_early_init(void) void hash_init(void) { + val ghu = func_n1(get_hash_userdata); + weak_keys_k = intern(lit("weak-keys"), keyword_package); weak_vals_k = intern(lit("weak-vals"), keyword_package); weak_and_k = intern(lit("weak-and"), keyword_package); @@ -2105,7 +2107,6 @@ void hash_init(void) eq_based_k = intern(lit("eq-based"), keyword_package); userdata_k = intern(lit("userdata"), keyword_package); hash_seed_s = intern(lit("*hash-seed*"), user_package); - val ghu = func_n1(get_hash_userdata); hash_cls->cls_sym = hash_s; hash_iter_cls->cls_sym = hash_iter_s; @@ -2256,9 +2256,10 @@ static val revlist(val in, val *tail) loc list_collect_revappend(loc ptail, val obj) { val last; - obj = nullify(obj); val tailobj = deref(ptail); + obj = nullify(obj); + again: switch (type(tailobj)) { case CONS: @@ -2520,10 +2521,11 @@ static val sub_iter(val obj, val from, val to) { val self = lit("sub"); seq_iter_t iter; - seq_iter_init(self, &iter, obj); val idx = zero, elem; list_collect_decl (out, ptail); + seq_iter_init(self, &iter, obj); + if (from == t) return nil; @@ -5443,10 +5445,11 @@ val replace_str(val str_in, val items, val from, val to) c_str(items, self), c_num(len_it, self)); } else { seq_iter_t item_iter; - seq_iter_init(self, &item_iter, items); cnum f = c_num(from, self); cnum t = c_num(to, self); + seq_iter_init(self, &item_iter, items); + for (; f != t; f++) str_in->st.str[f] = c_chr(seq_geti(&item_iter)); } @@ -6719,9 +6722,9 @@ val make_sym(val name) } } -val gensym(val prefix) +val gensym(val prefix_in) { - prefix = default_arg(prefix, lit("g")); + val prefix = default_arg(prefix_in, lit("g")); loc gs_loc = lookup_var_l(nil, gensym_counter_s); val name = format(nil, lit("~a~,04d"), prefix, set(gs_loc, plus(deref(gs_loc), one)), nao); @@ -9220,11 +9223,12 @@ val replace_vec(val vec_in, val items, val from, val to) mut(vec_in); } else { seq_iter_t item_iter; - seq_iter_init(self, &item_iter, items); int mut_needed = 0; cnum f = c_num(from, self); cnum t = c_num(to, self); + seq_iter_init(self, &item_iter, items); + for (; f != t; f++) { val item = seq_geti(&item_iter); if (is_ptr(item)) @@ -10126,10 +10130,11 @@ val mapcar_listout(val fun, val seq) { val self = lit("mapcar"); seq_iter_t iter; - seq_iter_init(self, &iter, seq); val elem; list_collect_decl (out, ptail); + seq_iter_init(self, &iter, seq); + while (seq_get(&iter, &elem)) ptail = list_collect(ptail, funcall1(fun, elem)); @@ -10158,10 +10163,11 @@ val mappend(val fun, val seq) { val self = lit("mappend"); seq_iter_t iter; - seq_iter_init(self, &iter, seq); val elem; list_collect_decl (out, ptail); + seq_iter_init(self, &iter, seq); + while (seq_get(&iter, &elem)) ptail = list_collect_append(ptail, funcall1(fun, elem)); @@ -10172,9 +10178,10 @@ val mapdo(val fun, val seq) { val self = lit("mapdo"); seq_iter_t iter; - seq_iter_init(self, &iter, seq); val elem; + seq_iter_init(self, &iter, seq); + while (seq_get(&iter, &elem)) funcall1(fun, elem); @@ -10239,9 +10246,11 @@ static val window_map_list(val range, val boundary, val fun, val list, args->arg[i] = ref(boundary, num(j++)); for (;;) { + val item; args_decl (args_cp, ws); args_copy(args_cp, args); - val item = generic_funcall(fun, args_cp); + + item = generic_funcall(fun, args_cp); switch (op) { case WMAP_MAP: ptail = list_collect(ptail, item); break; @@ -10819,11 +10828,11 @@ val rot(val seq, val n_in) return seq; } -val find(val item, val seq, val testfun, val keyfun) +val find(val item, val seq, val testfun_in, val keyfun_in) { val self = lit("find"); - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_info_t si = seq_info(seq); switch (si.kind) { @@ -10877,11 +10886,11 @@ val find(val item, val seq, val testfun, val keyfun) } } -val rfind(val item, val seq, val testfun, val keyfun) +val rfind(val item, val seq, val testfun_in, val keyfun_in) { val self = lit("rfind"); - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_info_t si = seq_info(seq); switch (si.kind) { @@ -11199,11 +11208,11 @@ val rfind_if(val predi, val seq, val key) return found; } -val pos(val item, val seq, val testfun, val keyfun) +val pos(val item, val seq, val testfun_in, val keyfun_in) { val self = lit("pos"); - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_info_t si = seq_info(seq); switch (si.kind) { @@ -11260,11 +11269,11 @@ val pos(val item, val seq, val testfun, val keyfun) } } -val rpos(val item, val seq, val testfun, val keyfun) +val rpos(val item, val seq, val testfun_in, val keyfun_in) { val self = lit("rpos"); - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_info_t si = seq_info(seq); switch (si.kind) { @@ -11525,12 +11534,13 @@ val subst(val oldv, val newv, val seq, val testfun_in, val keyfun_in) { val self = lit("subst"); seq_iter_t iter; - seq_iter_init(self, &iter, seq); val elem; val testfun = default_arg(testfun_in, equal_f); val keyfun = default_arg(keyfun_in, identity_f); list_collect_decl (out, ptail); + seq_iter_init(self, &iter, seq); + while (seq_get(&iter, &elem)) { val key = funcall1(keyfun, elem); ptail = list_collect(ptail, if3(funcall2(testfun, oldv, key), newv, elem)); @@ -12003,7 +12013,7 @@ val drop_until(val pred, val seq, val keyfun) } } -val in(val seq, val item, val testfun, val keyfun) +val in(val seq, val item, val testfun_in, val keyfun_in) { val self = lit("in"); seq_info_t si = seq_info(seq); @@ -12015,8 +12025,8 @@ val in(val seq, val item, val testfun, val keyfun) case STR: case LSTR: { - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); val len = length_str(seq); val ind; @@ -12032,8 +12042,8 @@ val in(val seq, val item, val testfun, val keyfun) } case VEC: { - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); val len = length_vec(seq); val ind; @@ -12050,7 +12060,7 @@ val in(val seq, val item, val testfun, val keyfun) default: switch (si.kind) { case SEQ_HASHLIKE: - if (null_or_missing_p(testfun) && null_or_missing_p(keyfun)) + if (null_or_missing_p(testfun_in) && null_or_missing_p(keyfun_in)) return tnil(gethash_e(self, si.obj, item)); /* fallthrough */ case SEQ_LISTLIKE: @@ -12058,12 +12068,11 @@ val in(val seq, val item, val testfun, val keyfun) { seq_iter_t iter; val elem; + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_iter_init(self, &iter, seq); - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); - while (seq_get(&iter, &elem)) { val key = funcall1(keyfun, elem); if (funcall2(testfun, item, key)) @@ -12629,10 +12638,10 @@ val update(val seq, val fun) } static val search_common(val self, int from_right, - val seq, val key, val testfun, val keyfun) + val seq, val key, val testfun_in, val keyfun_in) { - testfun = default_arg(testfun, equal_f); - keyfun = default_arg(keyfun, identity_f); + val testfun = default_arg(testfun_in, equal_f); + val keyfun = default_arg(keyfun_in, identity_f); seq_iter_t si, ki; seq_iter_init(self, &si, seq); diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index ec88f378..d3d6640b 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -2008,8 +2008,9 @@ static void edit_in_editor(lino_t *l) { if (fo) { char cmd[256]; - snprintf(cmd, sizeof cmd, "%s %s", ed, path); int preserve = 0; + + snprintf(cmd, sizeof cmd, "%s %s", ed, path); tr(l->data, '\r', '\n'); if (lino_os.puts_file_fn(fo, l->data) && lino_os.puts_file_fn(fo, L"\n")) @@ -1232,12 +1232,13 @@ static int is_balanced_line(const wchar_t *line, void *ctx) }; int count[32], sp = 0; enum state state[32]; - count[sp] = 0; - state[sp] = ST_START; wchar_t ch; (void) ctx; + count[sp] = 0; + state[sp] = ST_START; + while ((ch = *line++) != 0) { again: if (sp >= 30) @@ -1104,8 +1104,8 @@ static void nfa_map_states(nfa_state_t *s, static void nfa_count_one(nfa_state_t *s, mem_t *ctx) { - (void) s; int *pcount = coerce(int *, ctx); + (void) s; (*pcount)++; } @@ -2346,10 +2346,10 @@ static void print_rec(val exp, val stream, int *semi_flag) val args = rest(exp); if (sym == set_s || sym == cset_s) { - putc_clear_flag(chr('['), stream, semi_flag); - val first_p = t; + putc_clear_flag(chr('['), stream, semi_flag); + if (sym == cset_s) { put_char(chr('^'), stream); first_p = nil; @@ -370,8 +370,8 @@ int sig_mask(int how, const small_sigset_t *set, small_sigset_t *oldset) if (sig_blocked_cache.set != pnew->set) { static sigset_t blank; sigset_t real_newset = blank, real_oldset; - sig_blocked_cache = *pnew; int ret; + sig_blocked_cache = *pnew; #if HAVE_VALGRIND VALGRIND_MAKE_MEM_DEFINED(&real_oldset, sizeof real_oldset); #endif @@ -4173,11 +4173,11 @@ struct strm_ctx *get_ctx(val stream) return s->ctx; } -val get_string(val stream_in, val nchars, val close_after_p) +val get_string(val stream_in, val nchars_in, val close_after_p) { val stream = default_arg_strict(stream_in, std_input); val strstream = make_string_output_stream(); - nchars = default_null_arg(nchars); + val nchars = default_null_arg(nchars_in); val ch; if (nchars) { @@ -1167,9 +1167,9 @@ static struct stslot *lookup_static_slot_desc(struct struct_type *st, val sym) } } } else { - slot_cache = coerce(slot_cache_set_t *, - chk_calloc(SLOT_CACHE_SIZE, - sizeof (slot_cache_set_t))); + slot_cache_set_t *slot_cache = coerce(slot_cache_set_t *, + chk_calloc(SLOT_CACHE_SIZE, + sizeof *slot_cache)); slot_cache_set_t *set = &slot_cache[id % SLOT_CACHE_SIZE]; val key = cons(sym, num_fast(id)); val sl = gethash(slot_hash, key); @@ -1734,14 +1734,13 @@ static val umethod_args_fun(val dargs, struct args *args) cnum da_nargs = da->fill + c_num(length(da->list), self); cnum index = 0; val strct = args_get(args, &index); + struct struct_inst *si = struct_handle_for_slot(strct, self, sym); args_decl(args_call, max(args->fill + da_nargs, ARGS_MIN)); args_add(args_call, strct); args_cat(args_call, da); args_normalize_exact(args_call, da_nargs + 1); args_cat_zap_from(args_call, args, index); - struct struct_inst *si = struct_handle_for_slot(strct, self, sym); - if (sym && symbolp(sym)) { loc ptr = lookup_slot(strct, si, sym); if (!nullocp(ptr)) @@ -2035,10 +2034,13 @@ val static_slot_type_reg(val slot, val strct) val get_special_slot(val obj, enum special_slot spidx) { val slot = *special_sym[spidx]; - if (opt_compat && opt_compat <= 224) + + if (opt_compat && opt_compat <= 224) { return maybe_slot(obj, slot); - struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle); - return get_special_static_slot(si->type, spidx, slot); + } else { + struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle); + return get_special_static_slot(si->type, spidx, slot); + } } val get_special_required_slot(val obj, enum special_slot spidx) @@ -271,10 +271,12 @@ val usleep_wrap(val usec) sig_save_enable; #if HAVE_POSIX_NANOSLEEP - struct timespec ts; - ts.tv_sec = u / 1000000; - ts.tv_nsec = (u % 1000000) * 1000; - retval = if3(nanosleep(&ts, 0) == 0, t, nil); + { + struct timespec ts; + ts.tv_sec = u / 1000000; + ts.tv_nsec = (u % 1000000) * 1000; + retval = if3(nanosleep(&ts, 0) == 0, t, nil); + } #elif HAVE_POSIX_SLEEP && HAVE_POSIX_USLEEP retval = if2(sleep(u / 1000000) == 0 && usleep(u % 1000000) == 0, t); @@ -2525,13 +2527,17 @@ val setrlimit_wrap(val resource, val rlim) { val self = lit("setrlimit"); struct rlimit rl; + rl.rlim_cur = c_unum(slot(rlim, cur_s), self); rl.rlim_max = c_unum(slot(rlim, max_s), self); - int res = setrlimit(c_int(resource, self), &rl); - if (res != 0) - uw_ethrowf(system_error_s, lit("~a failed for ~a: ~d/~s"), - self, resource, num(errno), errno_to_str(errno), nao); + { + int res = setrlimit(c_int(resource, self), &rl); + + if (res != 0) + uw_ethrowf(system_error_s, lit("~a failed for ~a: ~d/~s"), + self, resource, num(errno), errno_to_str(errno), nao); + } return t; } @@ -407,10 +407,11 @@ static val time_string_meth(val time_struct, val format) { val self = lit("(meth time-string)"); struct tm tms = all_zero_init; - time_struct_to_tm(&tms, time_struct, t, self); char buffer[512] = ""; char *fmt = utf8_dup_to(c_str(format, self)); + time_struct_to_tm(&tms, time_struct, t, self); + if (strftime(buffer, sizeof buffer, fmt, &tms) == 0) buffer[0] = 0; @@ -425,9 +426,10 @@ static val time_parse_meth(val time_struct, val format, val string) { val self = lit("(meth time-parse)"); struct tm tms = all_zero_init; - time_struct_to_tm(&tms, time_struct, nil, self); val ret = nil; + time_struct_to_tm(&tms, time_struct, nil, self); + { const wchar_t *w_str = c_str(string, self); const wchar_t *w_fmt = c_str(format, self); @@ -537,28 +537,30 @@ static val tr_do_delete_specific(val tree, struct tree *tr, val subtree, return subtree; } - val tr_key = if3(tr->key_fn, - funcall1(tr->key_fn, subtree->tn.key), - subtree->tn.key); - - if (if3(tr->less_fn, - funcall2(tr->less_fn, key, tr_key), - less(key, tr_key))) { - val le = subtree->tn.left; - return tr_do_delete_specific(tree, tr, le, subtree, key, thisnode); - } else if (if3(tr->equal_fn == nil, - equal(key, tr_key), - funcall2(tr->equal_fn, key, tr_key))) - { - uses_or2; - val le = subtree->tn.left; - val ri = subtree->tn.right; - return or2(tr_do_delete_specific(tree, tr, le, subtree, key, thisnode), - tr_do_delete_specific(tree, tr, ri, subtree, key, thisnode)); - } else { - val ri = subtree->tn.right; - return tr_do_delete_specific(tree, tr, ri, subtree, key, thisnode); + val tr_key = if3(tr->key_fn, + funcall1(tr->key_fn, subtree->tn.key), + subtree->tn.key); + + if (if3(tr->less_fn, + funcall2(tr->less_fn, key, tr_key), + less(key, tr_key))) + { + val le = subtree->tn.left; + return tr_do_delete_specific(tree, tr, le, subtree, key, thisnode); + } else if (if3(tr->equal_fn == nil, + equal(key, tr_key), + funcall2(tr->equal_fn, key, tr_key))) + { + uses_or2; + val le = subtree->tn.left; + val ri = subtree->tn.right; + return or2(tr_do_delete_specific(tree, tr, le, subtree, key, thisnode), + tr_do_delete_specific(tree, tr, ri, subtree, key, thisnode)); + } else { + val ri = subtree->tn.right; + return tr_do_delete_specific(tree, tr, ri, subtree, key, thisnode); + } } } @@ -1072,6 +1072,7 @@ static val revive_cont(val dc, val arg) mem_t *ptr; uw_frame_t *new_uw_stack = coerce(uw_frame_t *, space + UW_CONT_FRAME_BEFORE), *fr; int env_set = 0; + val result = nil; memcpy(space, cont->stack, cont->size); @@ -1101,7 +1102,7 @@ static val revive_cont(val dc, val arg) #endif } - uw_block_begin (cont->tag, result); + uw_block_beg (cont->tag, result); for (fr = new_uw_stack; ; fr = fr->uw.up) { if (!env_set && fr->uw.type == UW_MENV) { @@ -398,6 +398,16 @@ NORETURN void invalid_op(val self, val obj); return VAL; \ } while (0) +#define uw_block_beg(TAG, RESULTVAR) \ + do { \ + uw_frame_t uw_blk; \ + obj_t **uw_rslt = &RESULTVAR; \ + uw_push_block(&uw_blk, TAG); \ + if (extended_setjmp(uw_blk.bl.jb)) { \ + RESULTVAR = uw_blk.bl.result; \ + } else { \ + enum { dummy ## __LINE__ } + #define uw_block_begin(TAG, RESULTVAR) \ obj_t *RESULTVAR = nil; \ do { \ @@ -407,7 +417,7 @@ NORETURN void invalid_op(val self, val obj); if (extended_setjmp(uw_blk.bl.jb)) { \ RESULTVAR = uw_blk.bl.result; \ } else { \ - do { } while (0) + enum { dummy ## __LINE__ } #define uw_block_end \ } \ @@ -417,9 +427,12 @@ NORETURN void invalid_op(val self, val obj); #define uw_match_env_begin \ do { \ uw_frame_t uw_env; \ - uw_push_match_env(&uw_env) + uw_push_match_env(&uw_env); \ + { \ + enum { dummy ## __LINE__ } #define uw_match_env_end \ + } \ uw_pop_frame(&uw_env); \ } while (0) @@ -1142,18 +1142,20 @@ val vm_execute_closure(val fun, struct args *args) } while (fixparam >= 2) { - fixparam -= 2; - argw = vm.code[vm.ip++]; - unsigned xreg = vm_arg_operand_lo(argw); - unsigned yreg = vm_arg_operand_hi(argw); + vm_word_t aw = vm.code[vm.ip++]; + unsigned xreg = vm_arg_operand_lo(aw); + unsigned yreg = vm_arg_operand_hi(aw); vm_set(dspl, xreg, args_get(args, &ix)); vm_set(dspl, yreg, args_get(args, &ix)); + fixparam -= 2; + argw = aw; } if (fixparam) { - argw = vm.code[vm.ip++]; - unsigned xreg = vm_arg_operand_lo(argw); + vm_word_t aw = vm.code[vm.ip++]; + unsigned xreg = vm_arg_operand_lo(aw); vm_set(dspl, xreg, args_get(args, &ix)); + argw = aw; } if (variadic) { |