-
Notifications
You must be signed in to change notification settings - Fork 185
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split ruby.c in multiple files, about one file per Ruby class
- Loading branch information
Showing
41 changed files
with
3,508 additions
and
3,432 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
All *.c and *.h files in this directory are licensed under: | ||
|
||
Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved. This | ||
code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
redistribute it and/or modify it under the terms of the: | ||
|
||
Eclipse Public License version 2.0, or | ||
GNU General Public License version 2, or | ||
GNU Lesser General Public License version 2.1. | ||
|
||
These files contain code that is based on the Ruby API headers and implementation, | ||
copyright (C) Yukihiro Matsumoto, licensed under the 2-clause BSD licence | ||
as described in the file BSDL included with TruffleRuby. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include <truffleruby-impl.h> | ||
|
||
// Memory-related function, *alloc*, *free*, rb_mem* | ||
|
||
void ruby_malloc_size_overflow(size_t count, size_t elsize) { | ||
rb_raise(rb_eArgError, | ||
"malloc: possible integer overflow (%"PRIdSIZE"*%"PRIdSIZE")", | ||
count, elsize); | ||
} | ||
|
||
size_t xmalloc2_size(const size_t count, const size_t elsize) { | ||
size_t ret; | ||
if (rb_mul_size_overflow(count, elsize, SSIZE_MAX, &ret)) { | ||
ruby_malloc_size_overflow(count, elsize); | ||
} | ||
return ret; | ||
} | ||
|
||
void *ruby_xmalloc(size_t size) { | ||
return malloc(size); | ||
} | ||
|
||
void *ruby_xmalloc2(size_t n, size_t size) { | ||
size_t total_size = xmalloc2_size(n, size); | ||
if (total_size == 0) { | ||
total_size = 1; | ||
} | ||
return malloc(xmalloc2_size(n, total_size)); | ||
} | ||
|
||
void *ruby_xcalloc(size_t n, size_t size) { | ||
return calloc(n, size); | ||
} | ||
|
||
void *ruby_xrealloc(void *ptr, size_t new_size) { | ||
return realloc(ptr, new_size); | ||
} | ||
|
||
void *ruby_xrealloc2(void *ptr, size_t n, size_t size) { | ||
size_t len = size * n; | ||
if (n != 0 && size != len / n) { | ||
rb_raise(rb_eArgError, "realloc: possible integer overflow"); | ||
} | ||
return realloc(ptr, len); | ||
} | ||
|
||
void ruby_xfree(void *address) { | ||
free(address); | ||
} | ||
|
||
void *rb_alloc_tmp_buffer(volatile VALUE *store, long len) { | ||
if (len == 0) { | ||
len = 1; | ||
} | ||
void *ptr = malloc(len); | ||
*((void**)store) = ptr; | ||
return ptr; | ||
} | ||
|
||
void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t size, size_t cnt) { | ||
return rb_alloc_tmp_buffer(store, size); | ||
} | ||
|
||
void rb_free_tmp_buffer(volatile VALUE *store) { | ||
free(*((void**)store)); | ||
} | ||
|
||
void rb_mem_clear(VALUE *mem, long n) { | ||
for (int i = 0; i < n; i++) { | ||
mem[i] = Qnil; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include <truffleruby-impl.h> | ||
#include <internal.h> | ||
|
||
// Parsing Ruby arguments from C functions | ||
|
||
static VALUE rb_keyword_error_new(const char *error, VALUE keys) { | ||
long i = 0, len = RARRAY_LEN(keys); | ||
VALUE error_message = rb_sprintf("%s keyword%.*s", error, len > 1, "s"); | ||
|
||
if (len > 0) { | ||
rb_str_append(error_message, rb_str_new_cstr(": ")); | ||
while (1) { | ||
const VALUE k = RARRAY_AREF(keys, i); | ||
Check_Type(k, T_SYMBOL); /* wrong hash is given to rb_get_kwargs */ | ||
rb_str_append(error_message, rb_sym2str(k)); | ||
if (++i >= len) break; | ||
rb_str_append(error_message, rb_str_new_cstr(", ")); | ||
} | ||
} | ||
|
||
return rb_exc_new_str(rb_eArgError, error_message); | ||
} | ||
|
||
NORETURN(static void rb_keyword_error(const char *error, VALUE keys)) { | ||
rb_exc_raise(rb_keyword_error_new(error, keys)); | ||
} | ||
|
||
NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords)) { | ||
int i; | ||
for (i = 0; i < keywords; i++) { | ||
VALUE key = table[i]; | ||
rb_hash_delete(hash, key); | ||
} | ||
rb_keyword_error("unknown", rb_hash_keys(hash)); | ||
} | ||
|
||
static VALUE rb_tr_extract_keyword(VALUE keyword_hash, ID key, VALUE *values) { | ||
VALUE val = rb_hash_lookup2(keyword_hash, key, Qundef); | ||
if (values) { | ||
rb_hash_delete(keyword_hash, key); | ||
} | ||
return val; | ||
} | ||
|
||
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values) { | ||
int rest = 0; | ||
int extracted = 0; | ||
VALUE missing = Qnil; | ||
|
||
if (optional < 0) { | ||
rest = 1; | ||
optional = -1-optional; | ||
} | ||
|
||
for (int n = 0; n < required; n++) { | ||
VALUE val = rb_tr_extract_keyword(keyword_hash, table[n], values); | ||
if (values) { | ||
values[n] = val; | ||
} | ||
if (val == Qundef) { | ||
if (NIL_P(missing)) { | ||
missing = rb_ary_new(); | ||
} | ||
rb_ary_push(missing, table[n]); | ||
rb_keyword_error("missing", missing); | ||
} | ||
extracted++; | ||
} | ||
|
||
if (optional && !NIL_P(keyword_hash)) { | ||
for (int m = required; m < required + optional; m++) { | ||
VALUE val = rb_tr_extract_keyword(keyword_hash, table[m], values); | ||
if (values) { | ||
values[m] = val; | ||
} | ||
if (val != Qundef) { | ||
extracted++; | ||
} | ||
} | ||
} | ||
|
||
if (!rest && !NIL_P(keyword_hash)) { | ||
if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : extracted)) { | ||
unknown_keyword_error(keyword_hash, table, required + optional); | ||
} | ||
} | ||
|
||
for (int i = extracted; i < required + optional; i++) { | ||
values[i] = Qundef; | ||
} | ||
|
||
return extracted; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
#include <truffleruby-impl.h> | ||
|
||
// Array, rb_ary_* | ||
|
||
long rb_array_len(VALUE array) { | ||
return polyglot_get_array_size(rb_tr_unwrap(array)); | ||
} | ||
|
||
int RARRAY_LENINT(VALUE array) { | ||
return polyglot_get_array_size(rb_tr_unwrap(array)); | ||
} | ||
|
||
VALUE RARRAY_AREF(VALUE array, long index) { | ||
return rb_tr_wrap(polyglot_get_array_element(rb_tr_unwrap(array), (int) index)); | ||
} | ||
|
||
VALUE rb_Array(VALUE array) { | ||
return RUBY_CEXT_INVOKE("rb_Array", array); | ||
} | ||
|
||
VALUE *RARRAY_PTR_IMPL(VALUE array) { | ||
return (VALUE *) polyglot_as_i64_array(RUBY_CEXT_INVOKE_NO_WRAP("RARRAY_PTR", array)); | ||
} | ||
|
||
VALUE rb_ary_new() { | ||
return RUBY_CEXT_INVOKE("rb_ary_new"); | ||
} | ||
|
||
VALUE rb_ary_new_capa(long capacity) { | ||
return rb_tr_wrap(polyglot_invoke(RUBY_CEXT, "rb_ary_new_capa", capacity)); | ||
} | ||
|
||
VALUE rb_ary_new_from_args(long n, ...) { | ||
VALUE array = rb_ary_new_capa(n); | ||
va_list args; | ||
va_start(args, n); | ||
for (int i = 0; i < n; i++) { | ||
rb_ary_store(array, i, va_arg(args, VALUE)); | ||
} | ||
va_end(args); | ||
return array; | ||
} | ||
|
||
VALUE rb_ary_new_from_values(long n, const VALUE *values) { | ||
VALUE array = rb_ary_new_capa(n); | ||
for (int i = 0; i < n; i++) { | ||
rb_ary_store(array, i, values[i]); | ||
} | ||
return array; | ||
} | ||
|
||
VALUE rb_ary_push(VALUE array, VALUE value) { | ||
RUBY_INVOKE_NO_WRAP(array, "push", value); | ||
return array; | ||
} | ||
|
||
VALUE rb_ary_pop(VALUE array) { | ||
return RUBY_INVOKE(array, "pop"); | ||
} | ||
|
||
void rb_ary_store(VALUE array, long index, VALUE value) { | ||
RUBY_INVOKE_NO_WRAP(array, "[]=", LONG2FIX(index), value); | ||
} | ||
|
||
VALUE rb_ary_entry(VALUE array, long index) { | ||
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "[]", index)); | ||
} | ||
|
||
VALUE rb_ary_unshift(VALUE array, VALUE value) { | ||
return RUBY_INVOKE(array, "unshift", value); | ||
} | ||
|
||
VALUE rb_ary_aref(int n, const VALUE* values, VALUE array) { | ||
return RUBY_CEXT_INVOKE("send_splatted", array, rb_str_new_cstr("[]"), rb_ary_new4(n, values)); | ||
} | ||
|
||
VALUE rb_ary_clear(VALUE array) { | ||
return RUBY_INVOKE(array, "clear"); | ||
} | ||
|
||
VALUE rb_ary_delete(VALUE array, VALUE value) { | ||
return RUBY_INVOKE(array, "delete", value); | ||
} | ||
|
||
VALUE rb_ary_delete_at(VALUE array, long n) { | ||
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "delete_at", n)); | ||
} | ||
|
||
VALUE rb_ary_includes(VALUE array, VALUE value) { | ||
return RUBY_INVOKE(array, "include?", value); | ||
} | ||
|
||
VALUE rb_ary_join(VALUE array, VALUE sep) { | ||
return RUBY_INVOKE(array, "join", sep); | ||
} | ||
|
||
VALUE rb_ary_to_s(VALUE array) { | ||
return RUBY_INVOKE(array, "to_s"); | ||
} | ||
|
||
VALUE rb_ary_reverse(VALUE array) { | ||
return RUBY_INVOKE(array, "reverse!"); | ||
} | ||
|
||
VALUE rb_ary_shift(VALUE array) { | ||
return RUBY_INVOKE(array, "shift"); | ||
} | ||
|
||
VALUE rb_ary_concat(VALUE a, VALUE b) { | ||
return RUBY_INVOKE(a, "concat", b); | ||
} | ||
|
||
VALUE rb_ary_plus(VALUE a, VALUE b) { | ||
return RUBY_INVOKE(a, "+", b); | ||
} | ||
|
||
VALUE rb_ary_to_ary(VALUE array) { | ||
VALUE tmp = rb_check_array_type(array); | ||
|
||
if (!NIL_P(tmp)) return tmp; | ||
return rb_ary_new_from_args(1, array); | ||
} | ||
|
||
VALUE rb_ary_subseq(VALUE array, long start, long length) { | ||
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "[]", start, length)); | ||
} | ||
|
||
VALUE rb_ary_cat(VALUE array, const VALUE *cat, long n) { | ||
return RUBY_INVOKE(array, "concat", rb_ary_new4(n, cat)); | ||
} | ||
|
||
VALUE rb_ary_rotate(VALUE array, long n) { | ||
if (n != 0) { | ||
return rb_tr_wrap(polyglot_invoke(rb_tr_unwrap(array), "rotate!", n)); | ||
} | ||
return Qnil; | ||
} | ||
|
||
VALUE rb_ary_tmp_new(long capa) { | ||
return rb_ary_new_capa(capa); | ||
} |
Oops, something went wrong.