rbs 3.10.0 → 4.0.0.dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/comments.yml +3 -3
- data/.github/workflows/ruby.yml +24 -35
- data/.github/workflows/typecheck.yml +3 -1
- data/.github/workflows/windows.yml +2 -2
- data/.gitignore +0 -4
- data/CHANGELOG.md +0 -88
- data/README.md +1 -38
- data/Rakefile +20 -142
- data/Steepfile +1 -0
- data/config.yml +43 -1
- data/core/array.rbs +46 -100
- data/core/complex.rbs +21 -32
- data/core/dir.rbs +2 -2
- data/core/encoding.rbs +9 -6
- data/core/enumerable.rbs +3 -90
- data/core/enumerator.rbs +1 -18
- data/core/errno.rbs +0 -8
- data/core/errors.rbs +1 -28
- data/core/exception.rbs +2 -2
- data/core/fiber.rbs +4 -5
- data/core/file.rbs +12 -27
- data/core/file_test.rbs +1 -1
- data/core/float.rbs +22 -209
- data/core/gc.rbs +281 -417
- data/core/hash.rbs +727 -1024
- data/core/integer.rbs +38 -78
- data/core/io/buffer.rbs +7 -18
- data/core/io/wait.rbs +33 -11
- data/core/io.rbs +12 -14
- data/core/kernel.rbs +51 -57
- data/core/marshal.rbs +1 -1
- data/core/match_data.rbs +1 -1
- data/core/math.rbs +3 -42
- data/core/method.rbs +6 -14
- data/core/module.rbs +17 -88
- data/core/nil_class.rbs +3 -3
- data/core/numeric.rbs +16 -16
- data/core/object.rbs +3 -3
- data/core/object_space.rbs +15 -21
- data/core/proc.rbs +8 -15
- data/core/process.rbs +2 -2
- data/core/ractor.rbs +437 -278
- data/core/range.rbs +8 -7
- data/core/rational.rbs +24 -37
- data/core/rbs/unnamed/argf.rbs +2 -2
- data/core/rbs/unnamed/env_class.rbs +1 -1
- data/core/rbs/unnamed/random.rbs +2 -4
- data/core/regexp.rbs +20 -25
- data/core/ruby_vm.rbs +4 -6
- data/core/rubygems/errors.rbs +70 -3
- data/core/rubygems/rubygems.rbs +79 -11
- data/core/rubygems/version.rbs +3 -2
- data/core/set.rbs +359 -488
- data/core/string.rbs +1228 -3153
- data/core/struct.rbs +1 -1
- data/core/symbol.rbs +4 -4
- data/core/thread.rbs +29 -92
- data/core/time.rbs +9 -35
- data/core/trace_point.rbs +4 -7
- data/core/unbound_method.rbs +6 -14
- data/docs/collection.md +2 -2
- data/docs/gem.md +1 -0
- data/docs/sigs.md +3 -3
- data/ext/rbs_extension/ast_translation.c +1077 -944
- data/ext/rbs_extension/ast_translation.h +0 -7
- data/ext/rbs_extension/class_constants.c +83 -71
- data/ext/rbs_extension/class_constants.h +7 -4
- data/ext/rbs_extension/extconf.rb +2 -24
- data/ext/rbs_extension/legacy_location.c +172 -173
- data/ext/rbs_extension/legacy_location.h +3 -8
- data/ext/rbs_extension/main.c +289 -239
- data/ext/rbs_extension/rbs_extension.h +0 -3
- data/ext/rbs_extension/rbs_string_bridging.h +0 -4
- data/include/rbs/ast.h +98 -37
- data/include/rbs/defines.h +12 -38
- data/include/rbs/lexer.h +114 -126
- data/include/rbs/location.h +14 -14
- data/include/rbs/parser.h +37 -21
- data/include/rbs/string.h +5 -3
- data/include/rbs/util/rbs_allocator.h +19 -40
- data/include/rbs/util/rbs_assert.h +1 -12
- data/include/rbs/util/rbs_constant_pool.h +3 -3
- data/include/rbs/util/rbs_encoding.h +1 -3
- data/include/rbs/util/rbs_unescape.h +1 -2
- data/lib/rbs/ast/ruby/annotations.rb +119 -0
- data/lib/rbs/ast/ruby/comment_block.rb +221 -0
- data/lib/rbs/ast/ruby/declarations.rb +86 -0
- data/lib/rbs/ast/ruby/helpers/constant_helper.rb +24 -0
- data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
- data/lib/rbs/ast/ruby/members.rb +213 -0
- data/lib/rbs/buffer.rb +104 -24
- data/lib/rbs/cli/validate.rb +40 -35
- data/lib/rbs/cli.rb +5 -6
- data/lib/rbs/collection/config/lockfile_generator.rb +0 -1
- data/lib/rbs/collection.rb +0 -1
- data/lib/rbs/definition.rb +6 -1
- data/lib/rbs/definition_builder/ancestor_builder.rb +65 -62
- data/lib/rbs/definition_builder/method_builder.rb +45 -30
- data/lib/rbs/definition_builder.rb +44 -9
- data/lib/rbs/environment/class_entry.rb +69 -0
- data/lib/rbs/environment/module_entry.rb +66 -0
- data/lib/rbs/environment.rb +244 -218
- data/lib/rbs/environment_loader.rb +3 -3
- data/lib/rbs/errors.rb +5 -4
- data/lib/rbs/inline_parser/comment_association.rb +117 -0
- data/lib/rbs/inline_parser.rb +206 -0
- data/lib/rbs/location_aux.rb +35 -3
- data/lib/rbs/parser_aux.rb +11 -6
- data/lib/rbs/prototype/runtime.rb +2 -2
- data/lib/rbs/resolver/constant_resolver.rb +2 -2
- data/lib/rbs/resolver/type_name_resolver.rb +38 -124
- data/lib/rbs/source.rb +99 -0
- data/lib/rbs/subtractor.rb +4 -3
- data/lib/rbs/test/type_check.rb +0 -14
- data/lib/rbs/types.rb +1 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs.rb +13 -1
- data/lib/rdoc/discover.rb +1 -1
- data/lib/rdoc_plugin/parser.rb +1 -1
- data/rbs.gemspec +1 -0
- data/sig/ancestor_builder.rbs +1 -1
- data/sig/ast/ruby/annotations.rbs +110 -0
- data/sig/ast/ruby/comment_block.rbs +119 -0
- data/sig/ast/ruby/declarations.rbs +60 -0
- data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
- data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
- data/sig/ast/ruby/members.rbs +72 -0
- data/sig/buffer.rbs +63 -5
- data/sig/definition.rbs +1 -0
- data/sig/definition_builder.rbs +1 -1
- data/sig/environment/class_entry.rbs +50 -0
- data/sig/environment/module_entry.rbs +50 -0
- data/sig/environment.rbs +28 -133
- data/sig/errors.rbs +13 -6
- data/sig/inline_parser/comment_association.rbs +71 -0
- data/sig/inline_parser.rbs +87 -0
- data/sig/location.rbs +32 -7
- data/sig/manifest.yaml +1 -0
- data/sig/method_builder.rbs +7 -4
- data/sig/parser.rbs +16 -20
- data/sig/resolver/type_name_resolver.rbs +7 -38
- data/sig/source.rbs +48 -0
- data/sig/types.rbs +1 -4
- data/src/ast.c +290 -201
- data/src/lexer.c +2813 -2902
- data/src/lexer.re +4 -0
- data/src/lexstate.c +155 -169
- data/src/location.c +40 -40
- data/src/parser.c +2665 -2433
- data/src/string.c +48 -0
- data/src/util/rbs_allocator.c +77 -80
- data/src/util/rbs_assert.c +10 -10
- data/src/util/rbs_buffer.c +2 -2
- data/src/util/rbs_constant_pool.c +15 -13
- data/src/util/rbs_encoding.c +4062 -20097
- data/src/util/rbs_unescape.c +48 -85
- data/stdlib/bigdecimal/0/big_decimal.rbs +82 -100
- data/stdlib/bigdecimal-math/0/big_math.rbs +8 -169
- data/stdlib/cgi/0/core.rbs +396 -2
- data/stdlib/cgi/0/manifest.yaml +0 -1
- data/stdlib/coverage/0/coverage.rbs +1 -3
- data/stdlib/date/0/date.rbs +59 -67
- data/stdlib/date/0/date_time.rbs +1 -1
- data/stdlib/delegate/0/delegator.rbs +7 -10
- data/stdlib/erb/0/erb.rbs +347 -737
- data/stdlib/fileutils/0/fileutils.rbs +13 -18
- data/stdlib/forwardable/0/forwardable.rbs +0 -3
- data/stdlib/json/0/json.rbs +48 -68
- data/stdlib/net-http/0/net-http.rbs +0 -3
- data/stdlib/objspace/0/objspace.rbs +4 -9
- data/stdlib/open-uri/0/open-uri.rbs +0 -40
- data/stdlib/openssl/0/openssl.rbs +228 -331
- data/stdlib/optparse/0/optparse.rbs +3 -3
- data/{core → stdlib/pathname/0}/pathname.rbs +355 -255
- data/stdlib/psych/0/psych.rbs +3 -3
- data/stdlib/rdoc/0/rdoc.rbs +1 -1
- data/stdlib/resolv/0/resolv.rbs +68 -25
- data/stdlib/ripper/0/ripper.rbs +2 -5
- data/stdlib/singleton/0/singleton.rbs +0 -3
- data/stdlib/socket/0/socket.rbs +1 -13
- data/stdlib/socket/0/tcp_socket.rbs +2 -10
- data/stdlib/stringio/0/stringio.rbs +85 -1176
- data/stdlib/strscan/0/string_scanner.rbs +31 -31
- data/stdlib/tempfile/0/tempfile.rbs +3 -3
- data/stdlib/time/0/time.rbs +1 -1
- data/stdlib/timeout/0/timeout.rbs +7 -63
- data/stdlib/tsort/0/cyclic.rbs +0 -3
- data/stdlib/uri/0/common.rbs +2 -11
- data/stdlib/uri/0/file.rbs +1 -1
- data/stdlib/uri/0/generic.rbs +16 -17
- data/stdlib/uri/0/rfc2396_parser.rbs +7 -6
- data/stdlib/zlib/0/zstream.rbs +0 -1
- metadata +40 -12
- data/.clang-format +0 -74
- data/.clangd +0 -2
- data/.github/workflows/c-check.yml +0 -54
- data/core/ruby.rbs +0 -53
- data/docs/aliases.md +0 -79
- data/docs/encoding.md +0 -56
- data/ext/rbs_extension/compat.h +0 -10
- data/stdlib/cgi-escape/0/escape.rbs +0 -153
data/src/string.c
CHANGED
|
@@ -5,6 +5,54 @@
|
|
|
5
5
|
#include <stdio.h>
|
|
6
6
|
#include <ctype.h>
|
|
7
7
|
|
|
8
|
+
unsigned int rbs_utf8_string_to_codepoint(const rbs_string_t string) {
|
|
9
|
+
unsigned int codepoint = 0;
|
|
10
|
+
int remaining_bytes = 0;
|
|
11
|
+
|
|
12
|
+
const char *s = string.start;
|
|
13
|
+
const char *end = string.end;
|
|
14
|
+
|
|
15
|
+
if (s >= end) return 0; // End of string
|
|
16
|
+
|
|
17
|
+
if ((*s & 0x80) == 0) {
|
|
18
|
+
// Single byte character (0xxxxxxx)
|
|
19
|
+
return *s;
|
|
20
|
+
} else if ((*s & 0xE0) == 0xC0) {
|
|
21
|
+
// Two byte character (110xxxxx 10xxxxxx)
|
|
22
|
+
codepoint = *s & 0x1F;
|
|
23
|
+
remaining_bytes = 1;
|
|
24
|
+
} else if ((*s & 0xF0) == 0xE0) {
|
|
25
|
+
// Three byte character (1110xxxx 10xxxxxx 10xxxxxx)
|
|
26
|
+
codepoint = *s & 0x0F;
|
|
27
|
+
remaining_bytes = 2;
|
|
28
|
+
} else if ((*s & 0xF8) == 0xF0) {
|
|
29
|
+
// Four byte character (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
|
|
30
|
+
codepoint = *s & 0x07;
|
|
31
|
+
remaining_bytes = 3;
|
|
32
|
+
} else {
|
|
33
|
+
// Invalid UTF-8 sequence
|
|
34
|
+
return 0xFFFD; // Unicode replacement character
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
s++;
|
|
38
|
+
while (remaining_bytes > 0 && s < end) {
|
|
39
|
+
if ((*s & 0xC0) != 0x80) {
|
|
40
|
+
// Invalid continuation byte
|
|
41
|
+
return 0xFFFD;
|
|
42
|
+
}
|
|
43
|
+
codepoint = (codepoint << 6) | (*s & 0x3F);
|
|
44
|
+
s++;
|
|
45
|
+
remaining_bytes--;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (remaining_bytes > 0) {
|
|
49
|
+
// Incomplete sequence
|
|
50
|
+
return 0xFFFD;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return codepoint;
|
|
54
|
+
}
|
|
55
|
+
|
|
8
56
|
rbs_string_t rbs_string_new(const char *start, const char *end) {
|
|
9
57
|
return (rbs_string_t) {
|
|
10
58
|
.start = start,
|
data/src/util/rbs_allocator.c
CHANGED
|
@@ -3,14 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A simple arena allocator that can be freed all at once.
|
|
5
5
|
*
|
|
6
|
-
* This allocator maintains a linked list of pages, which come in two flavours:
|
|
7
|
-
* 1. Small allocation pages, which are the same size as the system page size.
|
|
8
|
-
* 2. Large allocation pages, which are the exact size requested, for sizes greater than the small page size.
|
|
9
|
-
*
|
|
10
|
-
* Small allocations always fit into the unused space at the end of the "head" page. If there isn't enough room, a new
|
|
11
|
-
* page is allocated, and the small allocation is placed at its start. This approach wastes that unused slack at the
|
|
12
|
-
* end of the previous page, but it means that allocations are instant and never scan the linked list to find a gap.
|
|
13
|
-
*
|
|
14
6
|
* This allocator doesn't support freeing individual allocations. Only the whole arena can be freed at once at the end.
|
|
15
7
|
*/
|
|
16
8
|
|
|
@@ -23,24 +15,22 @@
|
|
|
23
15
|
#include <inttypes.h>
|
|
24
16
|
|
|
25
17
|
#ifdef _WIN32
|
|
26
|
-
#include <windows.h>
|
|
18
|
+
#include <windows.h>
|
|
27
19
|
#else
|
|
28
|
-
#include <unistd.h>
|
|
29
|
-
#include <sys/types.h>
|
|
30
|
-
#include <sys/mman.h>
|
|
31
|
-
#include <fcntl.h>
|
|
20
|
+
#include <unistd.h>
|
|
21
|
+
#include <sys/types.h>
|
|
22
|
+
#include <sys/mman.h>
|
|
32
23
|
#endif
|
|
33
24
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
|
|
26
|
+
#define MAP_ANONYMOUS MAP_ANON
|
|
27
|
+
#endif
|
|
37
28
|
|
|
38
|
-
// The size of the payload in bytes.
|
|
39
|
-
size_t size;
|
|
40
29
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
struct rbs_allocator {
|
|
31
|
+
uintptr_t heap_ptr;
|
|
32
|
+
uintptr_t size;
|
|
33
|
+
};
|
|
44
34
|
|
|
45
35
|
static size_t get_system_page_size(void) {
|
|
46
36
|
#ifdef _WIN32
|
|
@@ -54,37 +44,74 @@ static size_t get_system_page_size(void) {
|
|
|
54
44
|
#endif
|
|
55
45
|
}
|
|
56
46
|
|
|
57
|
-
static
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
static void *map_memory(size_t size) {
|
|
48
|
+
#ifdef _WIN32
|
|
49
|
+
LPVOID result = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
50
|
+
rbs_assert(result != NULL, "VirtualAlloc failed");
|
|
51
|
+
#else
|
|
52
|
+
void *result = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
|
53
|
+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
54
|
+
rbs_assert(result != MAP_FAILED, "mmap failed");
|
|
55
|
+
#endif
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
63
58
|
|
|
64
|
-
|
|
59
|
+
static void destroy_memory(void *memory, size_t size) {
|
|
60
|
+
#ifdef _WIN32
|
|
61
|
+
VirtualFree(memory, 0, MEM_RELEASE);
|
|
62
|
+
#else
|
|
63
|
+
munmap(memory, size);
|
|
64
|
+
#endif
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
static void guard_page(void *memory, size_t page_size) {
|
|
68
|
+
#ifdef _WIN32
|
|
69
|
+
DWORD old_protect_;
|
|
70
|
+
BOOL result = VirtualProtect(memory, page_size, PAGE_NOACCESS, &old_protect_);
|
|
71
|
+
rbs_assert(result != 0, "VirtualProtect failed");
|
|
72
|
+
#else
|
|
73
|
+
int result = mprotect(memory, page_size, PROT_NONE);
|
|
74
|
+
rbs_assert(result == 0, "mprotect failed");
|
|
75
|
+
#endif
|
|
76
|
+
}
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
static size_t rbs_allocator_default_mem(void) {
|
|
79
|
+
size_t kib = 1024;
|
|
80
|
+
size_t mib = kib * 1024;
|
|
81
|
+
size_t gib = mib * 1024;
|
|
82
|
+
return 4 * gib;
|
|
83
|
+
}
|
|
71
84
|
|
|
72
|
-
|
|
85
|
+
static inline bool is_power_of_two(uintptr_t value) {
|
|
86
|
+
return value > 0 && (value & (value - 1)) == 0;
|
|
87
|
+
}
|
|
73
88
|
|
|
74
|
-
|
|
75
|
-
|
|
89
|
+
// Align `val' to nearest multiple of `alignment'.
|
|
90
|
+
static uintptr_t align(uintptr_t size, uintptr_t alignment) {
|
|
91
|
+
rbs_assert(is_power_of_two(alignment), "alignment is not a power of two");
|
|
92
|
+
return (size + alignment - 1) & ~(alignment - 1);
|
|
93
|
+
}
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
rbs_allocator_t *rbs_allocator_init(void) {
|
|
96
|
+
size_t size = rbs_allocator_default_mem();
|
|
97
|
+
size_t page_size = get_system_page_size();
|
|
98
|
+
size = align(size, page_size);
|
|
99
|
+
void *mem = map_memory(size + page_size);
|
|
100
|
+
// Guard page; remove range checks in alloc fast path and hard fail if we
|
|
101
|
+
// consume all memory
|
|
102
|
+
void *last_page = (char *) mem + size;
|
|
103
|
+
guard_page(last_page, page_size);
|
|
104
|
+
uintptr_t start = (uintptr_t) mem;
|
|
105
|
+
rbs_allocator_t header = (rbs_allocator_t) {
|
|
106
|
+
.heap_ptr = start + sizeof header,
|
|
107
|
+
.size = size + page_size,
|
|
108
|
+
};
|
|
109
|
+
memcpy(mem, &header, sizeof header);
|
|
110
|
+
return (rbs_allocator_t *) mem;
|
|
78
111
|
}
|
|
79
112
|
|
|
80
113
|
void rbs_allocator_free(rbs_allocator_t *allocator) {
|
|
81
|
-
|
|
82
|
-
while (page) {
|
|
83
|
-
rbs_allocator_page_t *next = page->next;
|
|
84
|
-
free(page);
|
|
85
|
-
page = next;
|
|
86
|
-
}
|
|
87
|
-
free(allocator);
|
|
114
|
+
destroy_memory((void *) allocator, allocator->size);
|
|
88
115
|
}
|
|
89
116
|
|
|
90
117
|
// Allocates `new_size` bytes from `allocator`, aligned to an `alignment`-byte boundary.
|
|
@@ -98,51 +125,21 @@ void *rbs_allocator_realloc_impl(rbs_allocator_t *allocator, void *ptr, size_t o
|
|
|
98
125
|
|
|
99
126
|
// Allocates `size` bytes from `allocator`, aligned to an `alignment`-byte boundary.
|
|
100
127
|
void *rbs_allocator_malloc_impl(rbs_allocator_t *allocator, size_t size, size_t alignment) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// This simple allocator can only put small allocations into the head page.
|
|
107
|
-
// Naively prepending this large allocation page to the head of the allocator before the previous head page
|
|
108
|
-
// would waste the remaining space in the head page.
|
|
109
|
-
// So instead, we'll splice in the large page *after* the head page.
|
|
110
|
-
//
|
|
111
|
-
// +-------+ +-----------+ +-----------+
|
|
112
|
-
// | arena | | head page | | new_page |
|
|
113
|
-
// |-------| |-----------+ |-----------+
|
|
114
|
-
// | *page |--->| size | +--->| size | +---> ... previous tail
|
|
115
|
-
// +-------+ | offset | | | offset | |
|
|
116
|
-
// | *next ----+---+ | *next ----+---+
|
|
117
|
-
// | ... | | ... |
|
|
118
|
-
// +-----------+ +-----------+
|
|
119
|
-
//
|
|
120
|
-
new_page->next = allocator->page->next;
|
|
121
|
-
allocator->page->next = new_page;
|
|
122
|
-
|
|
123
|
-
uintptr_t pointer = (uintptr_t) new_page + sizeof(rbs_allocator_page_t);
|
|
124
|
-
return (void *) pointer;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
rbs_allocator_page_t *page = allocator->page;
|
|
128
|
-
if (page->used + size > page->size) {
|
|
129
|
-
// Not enough space. Allocate a new small page and prepend it to the allocator's linked list.
|
|
130
|
-
rbs_allocator_page_t *new_page = rbs_allocator_page_new(allocator->default_page_payload_size);
|
|
131
|
-
new_page->next = allocator->page;
|
|
132
|
-
allocator->page = new_page;
|
|
133
|
-
page = new_page;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
uintptr_t pointer = (uintptr_t) page + sizeof(rbs_allocator_page_t) + page->used;
|
|
137
|
-
page->used += size;
|
|
138
|
-
return (void *) pointer;
|
|
128
|
+
rbs_assert(size % alignment == 0, "size must be a multiple of the alignment. size: %zu, alignment: %zu", size, alignment);
|
|
129
|
+
uintptr_t aligned = align(allocator->heap_ptr, alignment);
|
|
130
|
+
allocator->heap_ptr = aligned + size;
|
|
131
|
+
return (void *) aligned;
|
|
139
132
|
}
|
|
140
133
|
|
|
141
134
|
// Note: This will eagerly fill with zeroes, unlike `calloc()` which can map a page in a page to be zeroed lazily.
|
|
142
135
|
// It's assumed that callers to this function will immediately write to the allocated memory, anyway.
|
|
143
136
|
void *rbs_allocator_calloc_impl(rbs_allocator_t *allocator, size_t count, size_t size, size_t alignment) {
|
|
144
137
|
void *p = rbs_allocator_malloc_many_impl(allocator, count, size, alignment);
|
|
138
|
+
#if defined(__linux__)
|
|
139
|
+
// mmap with MAP_ANONYMOUS gives zero-filled pages.
|
|
140
|
+
#else
|
|
145
141
|
memset(p, 0, count * size);
|
|
142
|
+
#endif
|
|
146
143
|
return p;
|
|
147
144
|
}
|
|
148
145
|
|
data/src/util/rbs_assert.c
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
#include <stdlib.h>
|
|
6
6
|
#include <stdbool.h>
|
|
7
7
|
|
|
8
|
-
void
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
void rbs_assert(bool condition, const char *fmt, ...) {
|
|
9
|
+
if (condition) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
va_list args;
|
|
14
|
+
va_start(args, fmt);
|
|
15
|
+
vfprintf(stderr, fmt, args);
|
|
16
|
+
va_end(args);
|
|
17
|
+
fprintf(stderr, "\n");
|
|
18
|
+
exit(EXIT_FAILURE);
|
|
19
19
|
}
|
data/src/util/rbs_buffer.c
CHANGED
|
@@ -25,7 +25,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
|
|
|
25
25
|
if (next_length > buffer->capacity) {
|
|
26
26
|
size_t old_capacity = buffer->capacity;
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
rbs_assert(old_capacity != 0, "Precondition: capacity must be at least 1. Got %zu", old_capacity);
|
|
29
29
|
|
|
30
30
|
size_t new_capacity = buffer->capacity * 2;
|
|
31
31
|
|
|
@@ -34,7 +34,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
char *new_value = rbs_allocator_realloc(allocator, buffer->value, old_capacity, new_capacity, char);
|
|
37
|
-
|
|
37
|
+
rbs_assert(new_value != NULL, "Failed to append to buffer. Old capacity: %zu, new capacity: %zu", old_capacity, new_capacity);
|
|
38
38
|
|
|
39
39
|
buffer->value = new_value;
|
|
40
40
|
buffer->capacity = new_capacity;
|
|
@@ -37,7 +37,7 @@ next_power_of_two(uint32_t v) {
|
|
|
37
37
|
return v;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
static bool is_power_of_two(uint32_t size) {
|
|
41
41
|
return (size & (size - 1)) == 0;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -46,7 +46,7 @@ RBS_ATTRIBUTE_UNUSED static bool is_power_of_two(uint32_t size) {
|
|
|
46
46
|
*/
|
|
47
47
|
static inline bool
|
|
48
48
|
rbs_constant_pool_resize(rbs_constant_pool_t *pool) {
|
|
49
|
-
|
|
49
|
+
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
|
|
50
50
|
|
|
51
51
|
uint32_t next_capacity = pool->capacity * 2;
|
|
52
52
|
if (next_capacity < pool->capacity) return false;
|
|
@@ -57,8 +57,8 @@ rbs_constant_pool_resize(rbs_constant_pool_t *pool) {
|
|
|
57
57
|
void *next = calloc(next_capacity, element_size);
|
|
58
58
|
if (next == NULL) return false;
|
|
59
59
|
|
|
60
|
-
rbs_constant_pool_bucket_t *next_buckets =
|
|
61
|
-
rbs_constant_t *next_constants = (
|
|
60
|
+
rbs_constant_pool_bucket_t *next_buckets = next;
|
|
61
|
+
rbs_constant_t *next_constants = (void *)(((char *) next) + next_capacity * sizeof(rbs_constant_pool_bucket_t));
|
|
62
62
|
|
|
63
63
|
// For each bucket in the current constant pool, find the index in the
|
|
64
64
|
// next constant pool, and insert it.
|
|
@@ -96,13 +96,14 @@ rbs_constant_pool_resize(rbs_constant_pool_t *pool) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// This storage is initialized by `Init_rbs_extension()` in `main.c`.
|
|
99
|
-
static rbs_constant_pool_t RBS_GLOBAL_CONSTANT_POOL_STORAGE = {
|
|
99
|
+
static rbs_constant_pool_t RBS_GLOBAL_CONSTANT_POOL_STORAGE = {};
|
|
100
100
|
rbs_constant_pool_t *RBS_GLOBAL_CONSTANT_POOL = &RBS_GLOBAL_CONSTANT_POOL_STORAGE;
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
103
|
* Initialize a new constant pool with a given capacity.
|
|
104
104
|
*/
|
|
105
|
-
bool
|
|
105
|
+
bool
|
|
106
|
+
rbs_constant_pool_init(rbs_constant_pool_t *pool, uint32_t capacity) {
|
|
106
107
|
const uint32_t maximum = (~((uint32_t) 0));
|
|
107
108
|
if (capacity >= ((maximum / 2) + 1)) return false;
|
|
108
109
|
|
|
@@ -111,8 +112,8 @@ bool rbs_constant_pool_init(rbs_constant_pool_t *pool, uint32_t capacity) {
|
|
|
111
112
|
void *memory = calloc(capacity, element_size);
|
|
112
113
|
if (memory == NULL) return false;
|
|
113
114
|
|
|
114
|
-
pool->buckets =
|
|
115
|
-
pool->constants = (
|
|
115
|
+
pool->buckets = memory;
|
|
116
|
+
pool->constants = (void *)(((char *)memory) + capacity * sizeof(rbs_constant_pool_bucket_t));
|
|
116
117
|
pool->size = 0;
|
|
117
118
|
pool->capacity = capacity;
|
|
118
119
|
return true;
|
|
@@ -123,7 +124,7 @@ bool rbs_constant_pool_init(rbs_constant_pool_t *pool, uint32_t capacity) {
|
|
|
123
124
|
*/
|
|
124
125
|
rbs_constant_t *
|
|
125
126
|
rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_id_t constant_id) {
|
|
126
|
-
|
|
127
|
+
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);
|
|
127
128
|
return &pool->constants[constant_id - 1];
|
|
128
129
|
}
|
|
129
130
|
|
|
@@ -133,7 +134,7 @@ rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_i
|
|
|
133
134
|
*/
|
|
134
135
|
rbs_constant_id_t
|
|
135
136
|
rbs_constant_pool_find(const rbs_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
|
136
|
-
|
|
137
|
+
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
|
|
137
138
|
const uint32_t mask = pool->capacity - 1;
|
|
138
139
|
|
|
139
140
|
uint32_t hash = rbs_constant_pool_hash(start, length);
|
|
@@ -161,7 +162,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
|
|
|
161
162
|
if (!rbs_constant_pool_resize(pool)) return RBS_CONSTANT_ID_UNSET;
|
|
162
163
|
}
|
|
163
164
|
|
|
164
|
-
|
|
165
|
+
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
|
|
165
166
|
const uint32_t mask = pool->capacity - 1;
|
|
166
167
|
|
|
167
168
|
uint32_t hash = rbs_constant_pool_hash(start, length);
|
|
@@ -202,7 +203,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
|
|
|
202
203
|
// IDs are allocated starting at 1, since the value 0 denotes a non-existent
|
|
203
204
|
// constant.
|
|
204
205
|
uint32_t id = ++pool->size;
|
|
205
|
-
|
|
206
|
+
rbs_assert(pool->size < ((uint32_t) (1 << 30)), "pool->size is too large. Got %i", pool->size);
|
|
206
207
|
|
|
207
208
|
*bucket = (rbs_constant_pool_bucket_t) {
|
|
208
209
|
.id = (unsigned int) (id & 0x3fffffff),
|
|
@@ -255,7 +256,8 @@ rbs_constant_pool_insert_constant(rbs_constant_pool_t *pool, const uint8_t *star
|
|
|
255
256
|
/**
|
|
256
257
|
* Free the memory associated with a constant pool.
|
|
257
258
|
*/
|
|
258
|
-
void
|
|
259
|
+
void
|
|
260
|
+
rbs_constant_pool_free(rbs_constant_pool_t *pool) {
|
|
259
261
|
// For each constant in the current constant pool, free the contents if the
|
|
260
262
|
// contents are owned.
|
|
261
263
|
for (uint32_t index = 0; index < pool->capacity; index++) {
|