Skip to content
13 changes: 8 additions & 5 deletions cont.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ enum context_type {

struct cont_saved_vm_stack {
VALUE *ptr;
size_t size;
#ifdef CAPTURE_JUST_VALID_VM_STACK
size_t slen; /* length of stack (head of ec->vm_stack) */
size_t clen; /* length of control frames (tail of ec->vm_stack) */
Expand Down Expand Up @@ -1089,15 +1090,15 @@ cont_free(void *ptr)

if (cont->type == CONTINUATION_CONTEXT) {
SIZED_FREE_N(cont->saved_ec.vm_stack, cont->saved_ec.vm_stack_size);
RUBY_FREE_UNLESS_NULL(cont->machine.stack);
SIZED_FREE_N(cont->machine.stack, cont->machine.stack_size);
}
else {
rb_fiber_t *fiber = (rb_fiber_t*)cont;
coroutine_destroy(&fiber->context);
fiber_stack_release_locked(fiber);
}

RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr);
SIZED_FREE_N(cont->saved_vm_stack.ptr, cont->saved_vm_stack.size);

VM_ASSERT(cont->jit_cont != NULL);
jit_cont_free(cont->jit_cont);
Expand Down Expand Up @@ -1293,7 +1294,7 @@ jit_cont_new(rb_execution_context_t *ec)
// We need to use calloc instead of something like ZALLOC to avoid triggering GC here.
// When this function is called from rb_thread_alloc through rb_threadptr_root_fiber_setup,
// the thread is still being prepared and marking it causes SEGV.
cont = calloc(1, sizeof(struct rb_jit_cont));
cont = ruby_mimcalloc(1, sizeof(struct rb_jit_cont));
if (cont == NULL)
rb_memerror();
cont->ec = ec;
Expand Down Expand Up @@ -1332,7 +1333,7 @@ jit_cont_free(struct rb_jit_cont *cont)
}
rb_native_mutex_unlock(&jit_cont_lock);

free(cont);
ruby_mimfree(cont);
}

// Call a given callback against all on-stack ISEQs.
Expand Down Expand Up @@ -1383,7 +1384,7 @@ rb_jit_cont_finish(void)
struct rb_jit_cont *cont, *next;
for (cont = first_jit_cont; cont != NULL; cont = next) {
next = cont->next;
free(cont); // Don't use xfree because it's allocated by calloc.
ruby_mimfree(cont); // Don't use xfree because it's allocated by mimcalloc.
}
rb_native_mutex_destroy(&jit_cont_lock);
}
Expand Down Expand Up @@ -1492,6 +1493,7 @@ cont_capture(volatile int *volatile stat)
#ifdef CAPTURE_JUST_VALID_VM_STACK
cont->saved_vm_stack.slen = ec->cfp->sp - ec->vm_stack;
cont->saved_vm_stack.clen = ec->vm_stack + ec->vm_stack_size - (VALUE*)ec->cfp;
cont->saved_vm_stack.size = cont->saved_vm_stack.slen + cont->saved_vm_stack.clen;
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, cont->saved_vm_stack.slen + cont->saved_vm_stack.clen);
MEMCPY(cont->saved_vm_stack.ptr,
ec->vm_stack,
Expand All @@ -1501,6 +1503,7 @@ cont_capture(volatile int *volatile stat)
VALUE,
cont->saved_vm_stack.clen);
#else
cont->saved_vm_stack.size = ec->vm_stack_size;
cont->saved_vm_stack.ptr = ALLOC_N(VALUE, ec->vm_stack_size);
MEMCPY(cont->saved_vm_stack.ptr, ec->vm_stack, VALUE, ec->vm_stack_size);
#endif
Expand Down
61 changes: 30 additions & 31 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -3674,13 +3674,15 @@ enc_path_skip_prefix(const char *path, const char *end, bool mb_enc, rb_encoding
if (path + 2 <= end && isdirsep(path[0]) && isdirsep(path[1])) {
path += 2;
while (path < end && isdirsep(*path)) path++;
if ((path = enc_path_next(path, end, mb_enc, enc)) < end && path[0] && path[1] && !isdirsep(path[1]))
if ((path = enc_path_next(path, end, mb_enc, enc)) < end &&
path + 2 <= end && !isdirsep(path[1])) {
path = enc_path_next(path + 1, end, mb_enc, enc);
}
return (char *)path;
}
#endif
#ifdef DOSISH_DRIVE_LETTER
if (has_drive_letter(path))
if (path + 2 <= end && has_drive_letter(path))
return (char *)(path + 2);
#endif
#endif /* defined(DOSISH_UNC) || defined(DOSISH_DRIVE_LETTER) */
Expand Down Expand Up @@ -4022,13 +4024,13 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
enc = rb_enc_get(fname);
BUFINIT();

if (s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */
if (s < fend && s[0] == '~' && abs_mode == 0) { /* execute only if NOT absolute_path() */
long userlen = 0;
if (isdirsep(s[1]) || s[1] == '\0') {
if (s + 1 == fend || isdirsep(s[1])) {
buf = 0;
b = 0;
rb_str_set_len(result, 0);
if (*++s) ++s;
if (++s < fend) ++s;
rb_default_home_dir(result);
}
else {
Expand Down Expand Up @@ -4058,8 +4060,8 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
#ifdef DOSISH_DRIVE_LETTER
/* skip drive letter */
else if (has_drive_letter(s)) {
if (isdirsep(s[2])) {
else if (s + 1 < fend && has_drive_letter(s)) {
if (s + 2 < fend && isdirsep(s[2])) {
/* specified drive letter, and full path */
/* skip drive letter */
BUFCHECK(bdiff + 2 >= buflen);
Expand Down Expand Up @@ -4093,7 +4095,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
}
#endif /* DOSISH_DRIVE_LETTER */
else if (!rb_is_absolute_path(s)) {
else if (s == fend || !rb_is_absolute_path(s)) {
if (!NIL_P(dname)) {
rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result);
rb_enc_associate(result, fs_enc_check(result, fname));
Expand All @@ -4106,7 +4108,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
p = e;
}
#if defined DOSISH || defined __CYGWIN__
if (isdirsep(*s)) {
if (s < fend && isdirsep(*s)) {
/* specified full path, but not drive letter nor UNC */
/* we need to get the drive letter or UNC share name */
p = skipprefix(buf, p, true, enc);
Expand All @@ -4118,7 +4120,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
else {
size_t len;
b = s;
do s++; while (isdirsep(*s));
do s++; while (s < fend && isdirsep(*s));
len = s - b;
p = buf + len;
BUFCHECK(bdiff >= buflen);
Expand All @@ -4140,16 +4142,17 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
root = skipprefix(buf, p+1, true, enc);

b = s;
while (*s) {
while (s < fend) {
switch (*s) {
case '.':
if (b == s++) { /* beginning of path element */
switch (*s) {
case '\0':
if (s == fend) {
b = s;
break;
}
switch (*s) {
case '.':
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
if (s+1 == fend || isdirsep(*(s+1))) {
/* We must go back to the parent */
char *n;
*p = '\0';
Expand All @@ -4163,7 +4166,7 @@ rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_na
}
#if USE_NTFS
else {
do ++s; while (istrailinggarbage(*s));
do ++s; while (s < fend && istrailinggarbage(*s));
}
#endif /* USE_NTFS */
break;
Expand Down Expand Up @@ -4931,11 +4934,11 @@ enc_find_basename(const char *name, long *baselen, long *alllen, bool mb_enc, rb
root = name;
#endif

while (isdirsep(*name)) {
while (name < end && isdirsep(*name)) {
name++;
}

if (!*name) {
if (name == end) {
p = name - 1;
f = 1;
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
Expand Down Expand Up @@ -5017,23 +5020,21 @@ ruby_enc_find_basename(const char *name, long *baselen, long *alllen, rb_encodin
static VALUE
rb_file_s_basename(int argc, VALUE *argv, VALUE _)
{
VALUE fname, fext;
const char *name, *p;
VALUE fname, fext = Qnil;
const char *name, *p, *fp = 0;
long f = 0, n;
rb_encoding *enc;

fext = Qnil;
if (rb_check_arity(argc, 1, 2) == 2) {
argc = rb_check_arity(argc, 1, 2);
fname = argv[0];
CheckPath(fname, name);
if (argc == 2) {
fext = argv[1];
StringValue(fext);
fp = StringValueCStr(fext);
check_path_encoding(fext);
enc = rb_str_enc_get(fext);
}
fname = argv[0];
CheckPath(fname, name);
if (NIL_P(fext) || !(enc = rb_enc_compatible(fname, fext))) {
enc = rb_str_enc_get(fname);
fext = Qnil;
}

n = RSTRING_LEN(fname);
Expand All @@ -5044,12 +5045,10 @@ rb_file_s_basename(int argc, VALUE *argv, VALUE _)
bool mb_enc = !rb_str_encindex_fastpath(rb_enc_to_index(enc));
p = enc_find_basename(name, &f, &n, mb_enc, enc);
if (n >= 0) {
if (NIL_P(fext)) {
if (!fp) {
f = n;
}
else {
const char *fp;
fp = StringValueCStr(fext);
if (!(f = rmext(p, f, n, fp, RSTRING_LEN(fext), enc))) {
f = n;
}
Expand Down Expand Up @@ -5139,7 +5138,7 @@ rb_file_dirname_n(VALUE fname, int n)
return rb_enc_str_new(".", 1, enc);
}
#ifdef DOSISH_DRIVE_LETTER
if (has_drive_letter(name) && isdirsep(*(name + 2))) {
if (name + 3 < end && has_drive_letter(name) && isdirsep(*(name + 2))) {
const char *top = skiproot(name + 2, end);
dirname = rb_enc_str_new(name, 3, enc);
rb_str_cat(dirname, top, p - top);
Expand All @@ -5148,7 +5147,7 @@ rb_file_dirname_n(VALUE fname, int n)
#endif
dirname = rb_enc_str_new(name, p - name, enc);
#ifdef DOSISH_DRIVE_LETTER
if (has_drive_letter(name) && root == name + 2 && p - name == 2)
if (root == name + 2 && p == root && name[1] == ':')
rb_str_cat(dirname, ".", 1);
#endif
return dirname;
Expand Down
6 changes: 1 addition & 5 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -1173,17 +1173,13 @@ hash_st_free(VALUE hash)
{
HASH_ASSERT(RHASH_ST_TABLE_P(hash));

st_table *tab = RHASH_ST_TABLE(hash);

xfree(tab->bins);
xfree(tab->entries);
rb_st_free_embedded_table(RHASH_ST_TABLE(hash));
}

static void
hash_st_free_and_clear_table(VALUE hash)
{
hash_st_free(hash);

RHASH_ST_CLEAR(hash);
}

Expand Down
2 changes: 0 additions & 2 deletions internal/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
#define RUBY_GC_INFO if(0)printf
#endif

#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}

#if STACK_GROW_DIRECTION > 0
# define STACK_UPPER(x, a, b) (a)
#elif STACK_GROW_DIRECTION < 0
Expand Down
2 changes: 2 additions & 0 deletions internal/set_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ int rb_set_foreach_check(set_table *, set_foreach_check_callback_func *, st_data
st_index_t rb_set_keys(set_table *table, st_data_t *keys, st_index_t size);
#define set_free_table rb_set_free_table
void rb_set_free_table(set_table *);
#define set_free_embedded_table rb_set_free_embedded_table
void set_free_embedded_table(set_table *tab);
#define set_table_clear rb_set_table_clear
void rb_set_table_clear(set_table *);
#define set_copy rb_set_copy
Expand Down
3 changes: 3 additions & 0 deletions internal/st.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ st_table *rb_st_replace(st_table *new_tab, st_table *old_tab);
st_table *rb_st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type, st_index_t size);
#define st_init_existing_table_with_size rb_st_init_existing_table_with_size

void rb_st_free_embedded_table(st_table *tab);
#define st_free_embedded_table rb_st_free_embedded_table

#endif
2 changes: 1 addition & 1 deletion marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2590,7 +2590,7 @@ marshal_compat_table_mark_and_move(void *tbl)
static int
marshal_compat_table_free_i(st_data_t key, st_data_t value, st_data_t _)
{
xfree((marshal_compat_t *)value);
SIZED_FREE((marshal_compat_t *)value);
return ST_CONTINUE;
}

Expand Down
2 changes: 1 addition & 1 deletion memory_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ rb_memory_view_release(rb_memory_view_t* view)
if (rv) {
unregister_exported_object(view->obj);
view->obj = Qnil;
xfree((void *)view->item_desc.components);
SIZED_FREE_N((rb_memory_view_item_component_t *)view->item_desc.components, view->item_desc.length);
}
return rv;
}
Expand Down
2 changes: 2 additions & 0 deletions parser_st.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ nonempty_memcpy(void *dest, const void *src, size_t n)
#define st_init_table_with_size rb_parser_st_init_table_with_size
#undef st_init_existing_table_with_size
#define st_init_existing_table_with_size rb_parser_st_init_existing_table_with_size
#undef st_free_embedded_table
#define st_free_embedded_table rb_parser_st_free_embedded_table
#undef st_insert
#define st_insert rb_parser_st_insert
#undef st_lookup
Expand Down
Loading