diff --git a/blob.c b/blob.c index d8fded8c..e927f4ff 100644 --- a/blob.c +++ b/blob.c @@ -35,7 +35,7 @@ pic_blob_bytevector(pic_state *pic) pic_value *argv; size_t argc, i; pic_blob *blob; - char *data; + unsigned char *data; pic_get_args(pic, "*", &argc, &argv); @@ -50,7 +50,7 @@ pic_blob_bytevector(pic_state *pic) pic_errorf(pic, "byte out of range"); } - *data++ = pic_int(argv[i]); + *data++ = (unsigned char)pic_int(argv[i]); } return pic_obj_value(blob); @@ -67,9 +67,12 @@ pic_blob_make_bytevector(pic_state *pic) if (b < 0 || b > 255) pic_errorf(pic, "byte out of range"); - blob = pic_make_blob(pic, k); + if (k < 0) + pic_errorf(pic, "make-bytevector: cannot create a bytevector of length %d", k); + + blob = pic_make_blob(pic, (size_t)k); for (i = 0; i < k; ++i) { - blob->data[i] = b; + blob->data[i] = (unsigned char)b; } return pic_obj_value(blob); @@ -82,7 +85,7 @@ pic_blob_bytevector_length(pic_state *pic) pic_get_args(pic, "b", &bv); - return pic_int_value(bv->len); + return pic_int_value((int)bv->len); } static pic_value @@ -107,7 +110,7 @@ pic_blob_bytevector_u8_set(pic_state *pic) if (v < 0 || v > 255) pic_errorf(pic, "byte out of range"); - bv->data[k] = v; + bv->data[k] = (unsigned char)v; return pic_none_value(); } @@ -123,7 +126,7 @@ pic_blob_bytevector_copy_i(pic_state *pic) case 3: start = 0; case 4: - end = from->len; + end = (int)from->len; } if (to == from && (start <= at && at < end)) { @@ -146,7 +149,7 @@ static pic_value pic_blob_bytevector_copy(pic_state *pic) { pic_blob *from, *to; - int n, start, end, i = 0; + int n, start, end, k, i = 0; n = pic_get_args(pic, "b|ii", &from, &start, &end); @@ -154,10 +157,15 @@ pic_blob_bytevector_copy(pic_state *pic) case 1: start = 0; case 2: - end = from->len; + end = (int)from->len; } - to = pic_make_blob(pic, end - start); + k = end - start; + + if (k < 0) + pic_errorf(pic, "make-bytevector: cannot create a bytevector of length %d", k); + + to = pic_make_blob(pic, (size_t)k); while (start < end) { to->data[i++] = from->data[start++]; } @@ -197,12 +205,12 @@ static pic_value pic_blob_list_to_bytevector(pic_state *pic) { pic_blob *blob; - char *data; + unsigned char *data; pic_value list, e; pic_get_args(pic, "o", &list); - blob = pic_make_blob(pic, pic_length(pic, list)); + blob = pic_make_blob(pic, (size_t)pic_length(pic, list)); data = blob->data; @@ -212,7 +220,7 @@ pic_blob_list_to_bytevector(pic_state *pic) if (pic_int(e) < 0 || pic_int(e) > 255) pic_errorf(pic, "byte out of range"); - *data++ = pic_int(e); + *data++ = (unsigned char)pic_int(e); } return pic_obj_value(blob); } @@ -230,7 +238,7 @@ pic_blob_bytevector_to_list(pic_state *pic) case 1: start = 0; case 2: - end = blob->len; + end = (int)blob->len; } list = pic_nil_value(); diff --git a/char.c b/char.c index a460fb2b..98eed6f7 100644 --- a/char.c +++ b/char.c @@ -31,7 +31,11 @@ pic_char_integer_to_char(pic_state *pic) pic_get_args(pic, "i", &i); - return pic_char_value(i); + if (i < 0 || i > 127) { + pic_errorf(pic, "integer->char: integer out of char range: %d", i); + } + + return pic_char_value((char)i); } #define DEFINE_CHAR_CMP(op, name) \ diff --git a/dict.c b/dict.c index 0746fbd9..13200c08 100644 --- a/dict.c +++ b/dict.c @@ -35,7 +35,7 @@ xh_value_hash(const void *key, void *data) break; } - return hash + pic_vtype(val); + return hash + (int)pic_vtype(val); } static int @@ -213,7 +213,7 @@ pic_dict_dictionary_size(pic_state *pic) pic_get_args(pic, "d", &dict); - return pic_int_value(pic_dict_size(pic, dict)); + return pic_int_value((int)pic_dict_size(pic, dict)); } static pic_value diff --git a/gc.c b/gc.c index 6a53a361..7768f8b9 100644 --- a/gc.c +++ b/gc.c @@ -706,7 +706,7 @@ gc_sweep_page(pic_state *pic, struct heap_page *page) #else static union header *NIL = NULL; #endif - union header *bp, *p, *s = NIL, *t; + union header *bp, *p, *s = NIL, *t = NIL; #if GC_DEBUG int c = 0; diff --git a/include/picrin/blob.h b/include/picrin/blob.h index 29a285e9..442c8a52 100644 --- a/include/picrin/blob.h +++ b/include/picrin/blob.h @@ -11,7 +11,7 @@ extern "C" { struct pic_blob { PIC_OBJECT_HEADER - char *data; + unsigned char *data; size_t len; }; diff --git a/include/picrin/cont.h b/include/picrin/cont.h index 3e948f73..645e6d9c 100644 --- a/include/picrin/cont.h +++ b/include/picrin/cont.h @@ -19,7 +19,7 @@ struct pic_escape { ptrdiff_t sp_offset; ptrdiff_t ci_offset; ptrdiff_t xp_offset; - int arena_idx; + size_t arena_idx; pic_code *ip; diff --git a/include/picrin/data.h b/include/picrin/data.h index 79b633a5..fec4cd7d 100644 --- a/include/picrin/data.h +++ b/include/picrin/data.h @@ -16,7 +16,7 @@ typedef struct { } pic_data_type; struct pic_data { - PIC_OBJECT_HEADER; + PIC_OBJECT_HEADER const pic_data_type *type; xhash storage; /* const char * to pic_value table */ void *data; diff --git a/include/picrin/value.h b/include/picrin/value.h index 9b1841d7..37dd58c0 100644 --- a/include/picrin/value.h +++ b/include/picrin/value.h @@ -10,10 +10,10 @@ extern "C" { #endif /** - * pic_sym is just an alias of uint32_t. + * pic_sym is just an alias of int. */ -typedef uint32_t pic_sym; +typedef int pic_sym; /** * `undef` values never seen from user-end: that is, @@ -71,7 +71,14 @@ pic_int(pic_value v) return u.i; } -#define pic_sym(v) ((v) & 0xfffffffful) +static inline int +pic_sym(pic_value v) +{ + union { int i; unsigned u; } u; + u.u = v & 0xfffffffful; + return u.i; +} + #define pic_char(v) ((v) & 0xfffffffful) #else @@ -215,9 +222,9 @@ pic_type(pic_value v) return PIC_TT_EOF; case PIC_VTYPE_HEAP: return ((struct pic_object *)pic_ptr(v))->tt; - default: - return -1; /* logic flaw */ } + + UNREACHABLE(); } static inline const char * @@ -357,10 +364,13 @@ pic_int_value(int i) static inline pic_value pic_symbol_value(pic_sym sym) { + union { int i; unsigned u; } u; pic_value v; + u.i = sym; + pic_init_value(v, PIC_VTYPE_SYMBOL); - v |= sym; + v |= u.u; return v; } diff --git a/include/picrin/xfile.h b/include/picrin/xfile.h index 15834184..4db6f836 100644 --- a/include/picrin/xfile.h +++ b/include/picrin/xfile.h @@ -111,7 +111,7 @@ xf_file_read(void *cookie, char *ptr, int size) FILE *file = cookie; int r; - r = fread(ptr, 1, size, file); + r = (int)fread(ptr, 1, (size_t)size, file); if (r < size && ferror(file)) { return -1; } @@ -127,7 +127,7 @@ xf_file_write(void *cookie, const char *ptr, int size) FILE *file = cookie; int r; - r = fwrite(ptr, 1, size, file); + r = (int)fwrite(ptr, 1, (size_t)size, file); if (r < size) { return -1; } @@ -212,8 +212,8 @@ xf_mem_read(void *cookie, char *ptr, int size) mem = (struct xf_membuf *)cookie; - if (size > mem->end - mem->pos) - size = mem->end - mem->pos; + if (size > (int)(mem->end - mem->pos)) + size = (int)(mem->end - mem->pos); memcpy(ptr, mem->buf + mem->pos, size); mem->pos += size; return size; @@ -228,7 +228,7 @@ xf_mem_write(void *cookie, const char *ptr, int size) if (mem->pos + size >= mem->capa) { mem->capa = (mem->pos + size) * 2; - mem->buf = realloc(mem->buf, mem->capa); + mem->buf = realloc(mem->buf, (size_t)mem->capa); } memcpy(mem->buf + mem->pos, ptr, size); mem->pos += size; @@ -344,12 +344,12 @@ xfread(void *ptr, size_t block, size_t nitems, xFILE *file) for (i = 0; i < nitems; ++i) { offset = 0; if (file->ungot != -1 && block > 0) { - buf[0] = file->ungot; + buf[0] = (char)file->ungot; offset += 1; file->ungot = -1; } while (offset < block) { - n = file->vtable.read(file->vtable.cookie, buf + offset, block - offset); + n = file->vtable.read(file->vtable.cookie, buf + offset, (int)(block - offset)); if (n < 0) { file->flags |= XF_ERR; goto exit; @@ -358,7 +358,7 @@ xfread(void *ptr, size_t block, size_t nitems, xFILE *file) file->flags |= XF_EOF; goto exit; } - offset += n; + offset += (unsigned)n; } memcpy(dst, buf, block); dst += block; @@ -378,12 +378,12 @@ xfwrite(const void *ptr, size_t block, size_t nitems, xFILE *file) for (i = 0; i < nitems; ++i) { offset = 0; while (offset < block) { - n = file->vtable.write(file->vtable.cookie, dst + offset, block - offset); + n = file->vtable.write(file->vtable.cookie, dst + offset, (int)(block - offset)); if (n < 0) { file->flags |= XF_ERR; goto exit; } - offset += n; + offset += (unsigned)n; } dst += block; } @@ -458,7 +458,7 @@ xfgets(char *str, int size, xFILE *file) if ((c = xfgetc(file)) == EOF) { break; } - str[i] = c; + str[i] = (char)c; } if (i == 0 && c == EOF) { return NULL; @@ -492,7 +492,7 @@ xfputc(int c, xFILE *file) { char buf[1]; - buf[0] = c; + buf[0] = (char)c; xfwrite(buf, 1, 1, file); if (xferror(file)) { @@ -516,7 +516,7 @@ xputchar(int c) static inline int xfputs(const char *str, xFILE *file) { - int len; + size_t len; len = strlen(str); xfwrite(str, len, 1, file); @@ -573,7 +573,7 @@ xvfprintf(xFILE *stream, const char *fmt, va_list ap) } va_end(ap2); - return sizeof buf; + return (int)(sizeof buf); } } diff --git a/include/picrin/xhash.h b/include/picrin/xhash.h index b43884df..1d3596ca 100644 --- a/include/picrin/xhash.h +++ b/include/picrin/xhash.h @@ -21,7 +21,7 @@ extern "C" { #define XHASH_RESIZE_RATIO 0.75 #define XHASH_ALIGNMENT 3 /* quad word alignment */ -#define XHASH_MASK (~((1 << XHASH_ALIGNMENT) - 1)) +#define XHASH_MASK (~(size_t)((1 << XHASH_ALIGNMENT) - 1)) #define XHASH_ALIGN(i) ((((i) - 1) & XHASH_MASK) + (1 << XHASH_ALIGNMENT)) typedef struct xh_entry { @@ -325,7 +325,7 @@ xh_ptr_hash(const void *key, void *data) { (void)data; - return (size_t)*(const void **)key; + return (int)(size_t)*(const void **)key; } static inline int diff --git a/include/picrin/xvect.h b/include/picrin/xvect.h index b98886e9..3701205e 100644 --- a/include/picrin/xvect.h +++ b/include/picrin/xvect.h @@ -45,7 +45,7 @@ xv_init(xvect *x, size_t width) x->data = NULL; x->width = width; x->size = 0; - x->mask = -1; + x->mask = (size_t)-1; x->head = 0; x->tail = 0; } diff --git a/number.c b/number.c index 4c13df35..2ed93a79 100644 --- a/number.c +++ b/number.c @@ -271,7 +271,7 @@ pic_number_abs(pic_state *pic) pic_get_args(pic, "F", &f, &e); if (e) { - return pic_int_value(fabs(f)); + return pic_int_value(abs((int)f)); } else { return pic_float_value(fabs(f)); @@ -283,17 +283,23 @@ pic_number_floor2(pic_state *pic) { int i, j; bool e1, e2; - double q, r; pic_get_args(pic, "II", &i, &e1, &j, &e2); - q = floor((double)i/j); - r = i - j * q; - if (e1 && e2) { - return pic_values2(pic, pic_int_value(q), pic_int_value(r)); + int k; + + k = (i < 0 && j < 0) || (0 <= i && 0 <= j) + ? i / j + : (i / j) - 1; + + return pic_values2(pic, pic_int_value(k), pic_int_value(i - k * j)); } else { + double q, r; + + q = floor((double)i/j); + r = i - j * q; return pic_values2(pic, pic_float_value(q), pic_float_value(r)); } } @@ -303,17 +309,18 @@ pic_number_trunc2(pic_state *pic) { int i, j; bool e1, e2; - double q, r; pic_get_args(pic, "II", &i, &e1, &j, &e2); - q = trunc((double)i/j); - r = i - j * q; - if (e1 && e2) { - return pic_values2(pic, pic_int_value(q), pic_int_value(r)); + return pic_values2(pic, pic_int_value(i/j), pic_int_value(i - (i/j) * j)); } else { + double q, r; + + q = trunc((double)i/j); + r = i - j * q; + return pic_values2(pic, pic_float_value(q), pic_float_value(r)); } } @@ -516,7 +523,7 @@ pic_number_exact(pic_state *pic) pic_get_args(pic, "f", &f); - return pic_int_value((int)round(f)); + return pic_int_value((int)(round(f))); } static pic_value @@ -564,7 +571,7 @@ pic_number_string_to_number(pic_state *pic) num = strtol(str, &eptr, radix); if (*eptr == '\0') { return pic_valid_int(num) - ? pic_int_value(num) + ? pic_int_value((int)num) : pic_float_value(num); } diff --git a/port.c b/port.c index 558a81b6..5cbcb1b8 100644 --- a/port.c +++ b/port.c @@ -87,12 +87,12 @@ pic_open_output_string(pic_state *pic) struct pic_string * pic_get_output_string(pic_state *pic, struct pic_port *port) { - long size; + size_t size; char *buf; /* get endpos */ xfflush(port->file); - size = xftell(port->file); + size = (size_t)xftell(port->file); xrewind(port->file); /* copy to buf */ @@ -347,7 +347,7 @@ pic_port_get_output_bytevector(pic_state *pic) { struct pic_port *port = pic_stdout(pic); pic_blob *blob; - long endpos; + size_t size; pic_get_args(pic, "|p", &port); @@ -355,12 +355,12 @@ pic_port_get_output_bytevector(pic_state *pic) /* get endpos */ xfflush(port->file); - endpos = xftell(port->file); + size = (size_t)xftell(port->file); xrewind(port->file); /* copy to buf */ - blob = pic_make_blob(pic, endpos); - xfread(blob->data, 1, endpos, port->file); + blob = pic_make_blob(pic, size); + xfread(blob->data, 1, size, port->file); return pic_obj_value(blob); } @@ -521,16 +521,21 @@ pic_port_read_blob(pic_state *pic) { struct pic_port *port = pic_stdin(pic); pic_blob *blob; - int k, i; + int k; + size_t i; - pic_get_args(pic, "i|p", &k, &port); + pic_get_args(pic, "i|p", &k, &port); assert_port_profile(port, PIC_PORT_IN | PIC_PORT_BINARY, PIC_PORT_OPEN, "read-bytevector"); - blob = pic_make_blob(pic, k); + if (k < 0) { + pic_errorf(pic, "read-bytevector: index must be non-negative %d", k); + } - i = xfread(blob->data, sizeof(char), k, port->file); - if ( i == 0 ) { + blob = pic_make_blob(pic, (size_t)k); + + i = xfread(blob->data, sizeof(char), (size_t)k, port->file); + if (i == 0) { return pic_eof_object(); } else { @@ -545,8 +550,9 @@ pic_port_read_blob_ip(pic_state *pic) { struct pic_port *port; struct pic_blob *bv; - int i, n, start, end, len; + int n, start, end; char *buf; + size_t i, len; n = pic_get_args(pic, "b|pii", &bv, &port, &start, &end); switch (n) { @@ -555,22 +561,27 @@ pic_port_read_blob_ip(pic_state *pic) case 2: start = 0; case 3: - end = bv->len; + end = (int)bv->len; } assert_port_profile(port, PIC_PORT_IN | PIC_PORT_BINARY, PIC_PORT_OPEN, "read-bytevector!"); - len = end - start; + + if (end - start < 0) { + pic_errorf(pic, "read-bytevector!: end index must be greater than or equal to start index"); + } + + len = (size_t)(end - start); buf = pic_calloc(pic, len, sizeof(char)); i = xfread(buf, sizeof(char), len, port->file); memcpy(bv->data + start, buf, i); pic_free(pic, buf); - if ( i == 0) { + if (i == 0) { return pic_eof_object(); } else { - return pic_int_value(i); + return pic_int_value((int)i); } } @@ -654,7 +665,7 @@ pic_port_write_blob(pic_state *pic) case 2: start = 0; case 3: - end = blob->len; + end = (int)blob->len; } assert_port_profile(port, PIC_PORT_OUT | PIC_PORT_BINARY, PIC_PORT_OPEN, "write-bytevector"); diff --git a/symbol.c b/symbol.c index c15a967d..0cbbf78a 100644 --- a/symbol.c +++ b/symbol.c @@ -57,7 +57,7 @@ pic_gensym(pic_state *pic, pic_sym base) } len = snprintf(NULL, 0, "%s%c%d", pic_symbol_name(pic, base), mark, uid); - str = pic_alloc(pic, len + 1); + str = pic_alloc(pic, (size_t)len + 1); sprintf(str, "%s%c%d", pic_symbol_name(pic, base), mark, uid); /* don't put the symbol to pic->syms to keep it uninterned */ diff --git a/time.c b/time.c index 43d770b3..a0a1ffb6 100644 --- a/time.c +++ b/time.c @@ -27,7 +27,7 @@ pic_current_jiffy(pic_state *pic) pic_get_args(pic, ""); c = clock(); - return pic_int_value(c); + return pic_int_value((int)c); } static pic_value diff --git a/var.c b/var.c index 45aae9b0..ea9cbff5 100644 --- a/var.c +++ b/var.c @@ -37,7 +37,7 @@ var_call(pic_state *pic) { struct pic_proc *self = pic_get_proc(pic); pic_value val, tmp, box, conv; - size_t n; + int n; n = pic_get_args(pic, "|oo", &val, &tmp); diff --git a/write.c b/write.c index 752964a1..fb01addc 100644 --- a/write.c +++ b/write.c @@ -211,7 +211,7 @@ write_core(struct writer_control *p, pic_value obj) size_t i; xh_entry *e, *it; int c; - float f; + double f; /* shared objects */ if (pic_vtype(obj) == PIC_VTYPE_HEAP