Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace assert with rbs_assert for better assertion message #23

Merged
merged 1 commit into from
Mar 17, 2025
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
3 changes: 2 additions & 1 deletion ext/rbs_extension/main.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "rbs_extension.h"
#include "rbs/util/rbs_assert.h"
#include "rbs/util/rbs_allocator.h"
#include "rbs/util/rbs_constant_pool.h"
#include "ast_translation.h"
Expand All @@ -15,7 +16,7 @@
* ```
* */
static NORETURN(void) raise_error(error *error, VALUE buffer) {
assert(error != NULL && "raise_error() called with NULL error");
rbs_assert(error != NULL, "raise_error() called with NULL error");

if (!error->syntax_error) {
rb_raise(rb_eRuntimeError, "Unexpected error");
Expand Down
9 changes: 9 additions & 0 deletions include/rbs/util/rbs_assert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef RBS_ASSERT_H
#define RBS_ASSERT_H

#include "rbs/defines.h"
#include <stdbool.h>

void rbs_assert(bool condition, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(2, 3);

#endif
3 changes: 2 additions & 1 deletion src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "rbs/encoding.h"
#include "rbs/rbs_string.h"
#include "rbs/rbs_unescape.h"
#include "rbs/util/rbs_assert.h"

#define INTERN(str) \
rbs_constant_pool_insert_constant( \
Expand Down Expand Up @@ -237,7 +238,7 @@ static bool parse_type_name(parserstate *state, TypeNameKind kind, range *rg, rb
ids = "class/module/constant name";
}

assert(ids != NULL && "Unknown kind of type");
rbs_assert(ids != NULL, "Unknown kind of type: %i", kind);

set_error(state, state->current_token, true, "expected one of %s", ids);
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/parserstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "rbs/parser.h"
#include "rbs/encoding.h"
#include "rbs/rbs_buffer.h"
#include "rbs/util/rbs_assert.h"

#include <stdio.h>

Expand Down Expand Up @@ -367,8 +368,7 @@ void rbs_parser_declare_type_variables(parserstate *parser, size_t count, const
);

if (!parser_insert_typevar(parser, name)) {
fprintf(stderr, "RuntimeError: %s\n", parser->error->message);
exit(1);
rbs_assert(false, "Failed to insert type variable. Message: %s", parser->error->message);
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/rbs_buffer.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "rbs/rbs_buffer.h"

#include <assert.h>
#include "rbs/util/rbs_assert.h"

bool rbs_buffer_init(rbs_allocator_t *allocator, rbs_buffer_t *buffer) {
size_t capacity = RBS_BUFFER_DEFAULT_CAPACITY;
Expand All @@ -26,7 +25,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
if (next_length > buffer->capacity) {
size_t old_capacity = buffer->capacity;

assert(old_capacity != 0 && "Precondition: capacity must be at least 1.");
rbs_assert(old_capacity != 0, "Precondition: capacity must be at least 1. Got %zu", old_capacity);

size_t new_capacity = buffer->capacity * 2;

Expand All @@ -35,7 +34,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
}

char *new_value = rbs_allocator_realloc(allocator, buffer->value, old_capacity, new_capacity, char);
assert(new_value != NULL && "Failed to append to buffer");
rbs_assert(new_value != NULL, "Failed to append to buffer. Old capacity: %zu, new capacity: %zu", old_capacity, new_capacity);

buffer->value = new_value;
buffer->capacity = new_capacity;
Expand Down
5 changes: 3 additions & 2 deletions src/rbs_encoding.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "rbs/rbs_encoding.h"
#include "rbs/util/rbs_assert.h"

#if defined(__GNUC__)
# define RBS_ATTRIBUTE_UNUSED __attribute__((unused))
Expand Down Expand Up @@ -2261,7 +2262,7 @@ static const uint8_t rbs_utf_8_dfa[] = {
*/
static rbs_unicode_codepoint_t
rbs_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
assert(n >= 0);
rbs_assert(n >= 0, "n must be greater than or equal to 0. Got %ti", n);

size_t maximum = (n > 4) ? 4 : ((size_t) n);
uint32_t codepoint;
Expand Down Expand Up @@ -2291,7 +2292,7 @@ rbs_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
*/
size_t
rbs_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) {
assert(n >= 0);
rbs_assert(n >= 0, "n must be greater than or equal to 0. Got %ti", n);

size_t maximum = (n > 4) ? 4 : ((size_t) n);
uint32_t state = 0;
Expand Down
7 changes: 4 additions & 3 deletions src/rbs_location.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "rbs/rbs_location.h"
#include "rbs/util/rbs_assert.h"

#include <stdio.h>

#define RBS_LOC_CHILDREN_SIZE(cap) (sizeof(rbs_loc_children) + sizeof(rbs_loc_entry) * ((cap) - 1))

void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, size_t capacity) {
assert(capacity <= sizeof(rbs_loc_entry_bitmap) * 8 && "Capacity is too large");
rbs_assert(capacity <= sizeof(rbs_loc_entry_bitmap) * 8, "Capacity %zu is too large. Max is %zu", capacity, sizeof(rbs_loc_entry_bitmap) * 8);

loc->children = rbs_allocator_malloc_impl(allocator, RBS_LOC_CHILDREN_SIZE(capacity), alignof(rbs_loc_children));

Expand All @@ -15,8 +16,8 @@ void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, siz
}

void rbs_loc_add_optional_child(rbs_location_t *loc, rbs_constant_id_t name, range r) {
assert(loc->children != NULL && "All children should have been pre-allocated with rbs_loc_alloc_children()");
assert((loc->children->len + 1 <= loc->children->cap) && "Not enough space was pre-allocated for the children.");
rbs_assert(loc->children != NULL, "All children should have been pre-allocated with rbs_loc_alloc_children()");
rbs_assert((loc->children->len + 1 <= loc->children->cap), "Not enough space was pre-allocated for the children. Children: %hu, Capacity: %hu", loc->children->len, loc->children->cap);

unsigned short i = loc->children->len++;
loc->children->entries[i].name = name;
Expand Down
6 changes: 3 additions & 3 deletions src/util/rbs_allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

#include "rbs/util/rbs_allocator.h"
#include "rbs/util/rbs_assert.h"

#include <stdlib.h>
#include <assert.h>
#include <string.h> // for memset()
#include <stdint.h>

Expand Down Expand Up @@ -138,7 +138,7 @@ void *rbs_allocator_realloc_impl(rbs_allocator_t *allocator, void *ptr, size_t o

// Allocates `size` bytes from `allocator`, aligned to an `alignment`-byte boundary.
void *rbs_allocator_malloc_impl(rbs_allocator_t *allocator, size_t size, size_t alignment) {
assert(size % alignment == 0 && "size must be a multiple of the alignment");
rbs_assert(size % alignment == 0, "size must be a multiple of the alignment. size: %zu, alignment: %zu", size, alignment);

if (default_page_payload_size < size) { // Big allocation, give it its own page.
// How much we need to pad the new page's payload in order to get an aligned pointer
Expand Down Expand Up @@ -176,7 +176,7 @@ void *rbs_allocator_malloc_impl(rbs_allocator_t *allocator, size_t size, size_t
allocator->page = new_page;

p = rbs_allocator_page_attempt_alloc(new_page, size, alignment);
assert(p != NULL && "Failed to allocate a new allocator page");
rbs_assert(p != NULL, "Failed to allocate a new allocator page");
return p;
}

Expand Down
19 changes: 19 additions & 0 deletions src/util/rbs_assert.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "rbs/util/rbs_assert.h"

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void rbs_assert(bool condition, const char *fmt, ...) {
if (condition) {
return;
}

va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
11 changes: 6 additions & 5 deletions src/util/rbs_constant_pool.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "rbs/util/rbs_constant_pool.h"
#include "rbs/util/rbs_assert.h"

/**
* A relatively simple hash function (djb2) that is used to hash strings. We are
Expand Down Expand Up @@ -48,7 +49,7 @@ is_power_of_two(uint32_t size) {
*/
static inline bool
rbs_constant_pool_resize(rbs_constant_pool_t *pool) {
assert(is_power_of_two(pool->capacity));
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);

uint32_t next_capacity = pool->capacity * 2;
if (next_capacity < pool->capacity) return false;
Expand Down Expand Up @@ -126,7 +127,7 @@ rbs_constant_pool_init(rbs_constant_pool_t *pool, uint32_t capacity) {
*/
rbs_constant_t *
rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_id_t constant_id) {
assert(constant_id != RBS_CONSTANT_ID_UNSET && constant_id <= pool->size);
rbs_assert(constant_id != RBS_CONSTANT_ID_UNSET && constant_id <= pool->size, "constant_id is not valid. Got %i, pool->size: %i", constant_id, pool->size);
return &pool->constants[constant_id - 1];
}

Expand All @@ -136,7 +137,7 @@ rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_i
*/
rbs_constant_id_t
rbs_constant_pool_find(const rbs_constant_pool_t *pool, const uint8_t *start, size_t length) {
assert(is_power_of_two(pool->capacity));
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
const uint32_t mask = pool->capacity - 1;

uint32_t hash = rbs_constant_pool_hash(start, length);
Expand Down Expand Up @@ -164,7 +165,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
if (!rbs_constant_pool_resize(pool)) return RBS_CONSTANT_ID_UNSET;
}

assert(is_power_of_two(pool->capacity));
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
const uint32_t mask = pool->capacity - 1;

uint32_t hash = rbs_constant_pool_hash(start, length);
Expand Down Expand Up @@ -205,7 +206,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
// IDs are allocated starting at 1, since the value 0 denotes a non-existent
// constant.
uint32_t id = ++pool->size;
assert(pool->size < ((uint32_t) (1 << 30)));
rbs_assert(pool->size < ((uint32_t) (1 << 30)), "pool->size is too large. Got %i", pool->size);

*bucket = (rbs_constant_pool_bucket_t) {
.id = (unsigned int) (id & 0x3fffffff),
Expand Down