Skip to content

Commit d83ddc3

Browse files
committed
Split ruby.c in multiple files, about one file per Ruby class
1 parent 19f457a commit d83ddc3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3508
-3432
lines changed

lib/cext/include/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define STR_SHARED_P(str) (str, false)
2222

2323
VALUE rb_hash_key_str(VALUE);
24+
VALUE rb_hash_keys(VALUE hash);
2425
VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
2526

2627
VALUE rb_int_positive_pow(long x, unsigned long y);

src/main/c/cext/LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
All *.c and *.h files in this directory are licensed under:
2+
3+
Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved. This
4+
code is released under a tri EPL/GPL/LGPL license. You can use it,
5+
redistribute it and/or modify it under the terms of the:
6+
7+
Eclipse Public License version 2.0, or
8+
GNU General Public License version 2, or
9+
GNU Lesser General Public License version 2.1.
10+
11+
These files contain code that is based on the Ruby API headers and implementation,
12+
copyright (C) Yukihiro Matsumoto, licensed under the 2-clause BSD licence
13+
as described in the file BSDL included with TruffleRuby.

src/main/c/cext/alloc.c

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <truffleruby-impl.h>
2+
3+
// Memory-related function, *alloc*, *free*, rb_mem*
4+
5+
void ruby_malloc_size_overflow(size_t count, size_t elsize) {
6+
rb_raise(rb_eArgError,
7+
"malloc: possible integer overflow (%"PRIdSIZE"*%"PRIdSIZE")",
8+
count, elsize);
9+
}
10+
11+
size_t xmalloc2_size(const size_t count, const size_t elsize) {
12+
size_t ret;
13+
if (rb_mul_size_overflow(count, elsize, SSIZE_MAX, &ret)) {
14+
ruby_malloc_size_overflow(count, elsize);
15+
}
16+
return ret;
17+
}
18+
19+
void *ruby_xmalloc(size_t size) {
20+
return malloc(size);
21+
}
22+
23+
void *ruby_xmalloc2(size_t n, size_t size) {
24+
size_t total_size = xmalloc2_size(n, size);
25+
if (total_size == 0) {
26+
total_size = 1;
27+
}
28+
return malloc(xmalloc2_size(n, total_size));
29+
}
30+
31+
void *ruby_xcalloc(size_t n, size_t size) {
32+
return calloc(n, size);
33+
}
34+
35+
void *ruby_xrealloc(void *ptr, size_t new_size) {
36+
return realloc(ptr, new_size);
37+
}
38+
39+
void *ruby_xrealloc2(void *ptr, size_t n, size_t size) {
40+
size_t len = size * n;
41+
if (n != 0 && size != len / n) {
42+
rb_raise(rb_eArgError, "realloc: possible integer overflow");
43+
}
44+
return realloc(ptr, len);
45+
}
46+
47+
void ruby_xfree(void *address) {
48+
free(address);
49+
}
50+
51+
void *rb_alloc_tmp_buffer(volatile VALUE *store, long len) {
52+
if (len == 0) {
53+
len = 1;
54+
}
55+
void *ptr = malloc(len);
56+
*((void**)store) = ptr;
57+
return ptr;
58+
}
59+
60+
void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t size, size_t cnt) {
61+
return rb_alloc_tmp_buffer(store, size);
62+
}
63+
64+
void rb_free_tmp_buffer(volatile VALUE *store) {
65+
free(*((void**)store));
66+
}
67+
68+
void rb_mem_clear(VALUE *mem, long n) {
69+
for (int i = 0; i < n; i++) {
70+
mem[i] = Qnil;
71+
}
72+
}

src/main/c/cext/args.c

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <truffleruby-impl.h>
2+
#include <internal.h>
3+
4+
// Parsing Ruby arguments from C functions
5+
6+
static VALUE rb_keyword_error_new(const char *error, VALUE keys) {
7+
long i = 0, len = RARRAY_LEN(keys);
8+
VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s");
9+
10+
if (len > 0) {
11+
rb_str_append(error_message, rb_str_new_cstr(": "));
12+
while (1) {
13+
const VALUE k = RARRAY_AREF(keys, i);
14+
Check_Type(k, T_SYMBOL); /* wrong hash is given to rb_get_kwargs */
15+
rb_str_append(error_message, rb_sym2str(k));
16+
if (++i >= len) break;
17+
rb_str_append(error_message, rb_str_new_cstr(", "));
18+
}
19+
}
20+
21+
return rb_exc_new_str(rb_eArgError, error_message);
22+
}
23+
24+
NORETURN(static void rb_keyword_error(const char *error, VALUE keys)) {
25+
rb_exc_raise(rb_keyword_error_new(error, keys));
26+
}
27+
28+
NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords)) {
29+
int i;
30+
for (i = 0; i < keywords; i++) {
31+
VALUE key = table[i];
32+
rb_hash_delete(hash, key);
33+
}
34+
rb_keyword_error("unknown", rb_hash_keys(hash));
35+
}
36+
37+
static VALUE rb_tr_extract_keyword(VALUE keyword_hash, ID key, VALUE *values) {
38+
VALUE val = rb_hash_lookup2(keyword_hash, key, Qundef);
39+
if (values) {
40+
rb_hash_delete(keyword_hash, key);
41+
}
42+
return val;
43+
}
44+
45+
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values) {
46+
int rest = 0;
47+
int extracted = 0;
48+
VALUE missing = Qnil;
49+
50+
if (optional < 0) {
51+
rest = 1;
52+
optional = -1-optional;
53+
}
54+
55+
for (int n = 0; n < required; n++) {
56+
VALUE val = rb_tr_extract_keyword(keyword_hash, table[n], values);
57+
if (values) {
58+
values[n] = val;
59+
}
60+
if (val == Qundef) {
61+
if (NIL_P(missing)) {
62+
missing = rb_ary_new();
63+
}
64+
rb_ary_push(missing, table[n]);
65+
rb_keyword_error("missing", missing);
66+
}
67+
extracted++;
68+
}
69+
70+
if (optional && !NIL_P(keyword_hash)) {
71+
for (int m = required; m < required + optional; m++) {
72+
VALUE val = rb_tr_extract_keyword(keyword_hash, table[m], values);
73+
if (values) {
74+
values[m] = val;
75+
}
76+
if (val != Qundef) {
77+
extracted++;
78+
}
79+
}
80+
}
81+
82+
if (!rest && !NIL_P(keyword_hash)) {
83+
if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : extracted)) {
84+
unknown_keyword_error(keyword_hash, table, required + optional);
85+
}
86+
}
87+
88+
for (int i = extracted; i < required + optional; i++) {
89+
values[i] = Qundef;
90+
}
91+
92+
return extracted;
93+
}

src/main/c/cext/array.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#include <truffleruby-impl.h>
2+
3+
// Array, rb_ary_*
4+
5+
long rb_array_len(VALUE array) {
6+
return polyglot_get_array_size(rb_tr_unwrap(array));
7+
}
8+
9+
int RARRAY_LENINT(VALUE array) {
10+
return polyglot_get_array_size(rb_tr_unwrap(array));
11+
}
12+
13+
VALUE RARRAY_AREF(VALUE array, long index) {
14+
return rb_tr_wrap(polyglot_get_array_element(rb_tr_unwrap(array), (int) index));
15+
}
16+
17+
VALUE rb_Array(VALUE array) {
18+
return RUBY_CEXT_INVOKE("rb_Array", array);
19+
}
20+
21+
VALUE *RARRAY_PTR_IMPL(VALUE array) {
22+
return (VALUE *) polyglot_as_i64_array(RUBY_CEXT_INVOKE_NO_WRAP("RARRAY_PTR", array));
23+
}
24+
25+
VALUE rb_ary_new() {
26+
return RUBY_CEXT_INVOKE("rb_ary_new");
27+
}
28+
29+
VALUE rb_ary_new_capa(long capacity) {
30+
return rb_tr_wrap(polyglot_invoke(RUBY_CEXT, "rb_ary_new_capa", capacity));
31+
}
32+
33+
VALUE rb_ary_new_from_args(long n, ...) {
34+
VALUE array = rb_ary_new_capa(n);
35+
va_list args;
36+
va_start(args, n);
37+
for (int i = 0; i < n; i++) {
38+
rb_ary_store(array, i, va_arg(args, VALUE));
39+
}
40+
va_end(args);
41+
return array;
42+
}
43+
44+
VALUE rb_ary_new_from_values(long n, const VALUE *values) {
45+
VALUE array = rb_ary_new_capa(n);
46+
for (int i = 0; i < n; i++) {
47+
rb_ary_store(array, i, values[i]);
48+
}
49+
return array;
50+
}
51+
52+
VALUE rb_ary_push(VALUE array, VALUE value) {
53+
RUBY_INVOKE_NO_WRAP(array, "push", value);
54+
return array;
55+
}
56+
57+
VALUE rb_ary_pop(VALUE array) {
58+
return RUBY_INVOKE(array, "pop");
59+
}
60+
61+
void rb_ary_store(VALUE array, long index, VALUE value) {
62+
RUBY_INVOKE_NO_WRAP(array, "[]=", LONG2FIX(index), value);
63+
}
64+
65+
VALUE rb_ary_entry(VALUE array, long index) {
66+
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "[]", index));
67+
}
68+
69+
VALUE rb_ary_unshift(VALUE array, VALUE value) {
70+
return RUBY_INVOKE(array, "unshift", value);
71+
}
72+
73+
VALUE rb_ary_aref(int n, const VALUE* values, VALUE array) {
74+
return RUBY_CEXT_INVOKE("send_splatted", array, rb_str_new_cstr("[]"), rb_ary_new4(n, values));
75+
}
76+
77+
VALUE rb_ary_clear(VALUE array) {
78+
return RUBY_INVOKE(array, "clear");
79+
}
80+
81+
VALUE rb_ary_delete(VALUE array, VALUE value) {
82+
return RUBY_INVOKE(array, "delete", value);
83+
}
84+
85+
VALUE rb_ary_delete_at(VALUE array, long n) {
86+
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "delete_at", n));
87+
}
88+
89+
VALUE rb_ary_includes(VALUE array, VALUE value) {
90+
return RUBY_INVOKE(array, "include?", value);
91+
}
92+
93+
VALUE rb_ary_join(VALUE array, VALUE sep) {
94+
return RUBY_INVOKE(array, "join", sep);
95+
}
96+
97+
VALUE rb_ary_to_s(VALUE array) {
98+
return RUBY_INVOKE(array, "to_s");
99+
}
100+
101+
VALUE rb_ary_reverse(VALUE array) {
102+
return RUBY_INVOKE(array, "reverse!");
103+
}
104+
105+
VALUE rb_ary_shift(VALUE array) {
106+
return RUBY_INVOKE(array, "shift");
107+
}
108+
109+
VALUE rb_ary_concat(VALUE a, VALUE b) {
110+
return RUBY_INVOKE(a, "concat", b);
111+
}
112+
113+
VALUE rb_ary_plus(VALUE a, VALUE b) {
114+
return RUBY_INVOKE(a, "+", b);
115+
}
116+
117+
VALUE rb_ary_to_ary(VALUE array) {
118+
VALUE tmp = rb_check_array_type(array);
119+
120+
if (!NIL_P(tmp)) return tmp;
121+
return rb_ary_new_from_args(1, array);
122+
}
123+
124+
VALUE rb_ary_subseq(VALUE array, long start, long length) {
125+
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "[]", start, length));
126+
}
127+
128+
VALUE rb_ary_cat(VALUE array, const VALUE *cat, long n) {
129+
return RUBY_INVOKE(array, "concat", rb_ary_new4(n, cat));
130+
}
131+
132+
VALUE rb_ary_rotate(VALUE array, long n) {
133+
if (n != 0) {
134+
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "rotate!", n));
135+
}
136+
return Qnil;
137+
}
138+
139+
VALUE rb_ary_tmp_new(long capa) {
140+
return rb_ary_new_capa(capa);
141+
}

0 commit comments

Comments
 (0)