diff --git a/tools/chibi-ffi b/tools/chibi-ffi index 0b73c636..06387ba2 100755 --- a/tools/chibi-ffi +++ b/tools/chibi-ffi @@ -1509,6 +1509,8 @@ (if (pair? (struct-fields type)) (let ((len (make-integer (length (struct-fields type))))) (cat " sexp_type_slots(" (type-id-name name) ") = SEXP_NULL;\n" + " sexp_type_field_len_base(" (type-id-name name) ")" + " = " (length (struct-fields type)) ";\n" (lambda () (do ((ls (reverse (struct-fields type)) (cdr ls))) ((not (pair? ls))) diff --git a/vm.c b/vm.c index fdb4bce9..08fa331e 100644 --- a/vm.c +++ b/vm.c @@ -1537,6 +1537,8 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { if (sexp_car(tmp1) == _ARG3) { _ARG3 = sexp_make_fixnum(i); break; } if (! sexp_fixnump(_ARG3)) sexp_raise("slotn-ref: not an integer", sexp_list1(ctx, _ARG3)); + if (sexp_unbox_fixnum(_ARG3) < 0 || sexp_unbox_fixnum(_ARG3) >= sexp_type_field_len_base(_ARG1)) + sexp_raise("slotn-ref: slot out of bounds", sexp_list2(ctx, _ARG3, sexp_make_fixnum(sexp_type_field_len_base(_ARG1)))); if (sexp_vectorp(sexp_type_getters(_ARG1))) { tmp1 = sexp_vector_ref(sexp_type_getters(_ARG1), _ARG3); if (sexp_opcodep(tmp1)) @@ -1561,12 +1563,14 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { if (sexp_car(tmp1) == _ARG3) { _ARG3 = sexp_make_fixnum(i); break; } if (! sexp_fixnump(_ARG3)) sexp_raise("slotn-set!: not an integer", sexp_list1(ctx, _ARG3)); + if (sexp_unbox_fixnum(_ARG3) < 0 || sexp_unbox_fixnum(_ARG3) >= sexp_type_field_len_base(_ARG1)) + sexp_raise("slotn-set!: slot out of bounds", sexp_list2(ctx, _ARG3, sexp_make_fixnum(sexp_type_field_len_base(_ARG1)))); if (sexp_vectorp(sexp_type_setters(_ARG1))) { tmp1 = sexp_vector_ref(sexp_type_setters(_ARG1), _ARG3); if (sexp_opcodep(tmp1)) _ARG4 = ((sexp_proc3)sexp_opcode_func(tmp1))(ctx, tmp1, 2, _ARG2, _ARG4); else - sexp_raise("slotn-ref: no setter defined", sexp_list1(ctx, _ARG3)); + sexp_raise("slotn-set!: no setter defined", sexp_list1(ctx, _ARG3)); } else sexp_slot_set(_ARG2, sexp_unbox_fixnum(_ARG3), _ARG4); top-=4;