@herb-tools/node 0.7.4 → 0.8.0
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.
- package/binding.gyp +8 -5
- package/dist/herb-node.esm.js +6 -6
- package/dist/herb-node.esm.js.map +1 -1
- package/extension/error_helpers.cpp +67 -9
- package/extension/error_helpers.h +4 -2
- package/extension/extension_helpers.cpp +20 -31
- package/extension/extension_helpers.h +7 -5
- package/extension/herb.cpp +10 -42
- package/extension/libherb/analyze.c +461 -249
- package/extension/libherb/analyze.h +10 -2
- package/extension/libherb/analyze_helpers.c +5 -0
- package/extension/libherb/analyze_helpers.h +3 -0
- package/extension/libherb/analyze_missing_end.c +147 -0
- package/extension/libherb/analyze_transform.c +196 -0
- package/extension/libherb/analyzed_ruby.c +23 -2
- package/extension/libherb/analyzed_ruby.h +4 -2
- package/extension/libherb/ast_node.c +14 -17
- package/extension/libherb/ast_node.h +4 -4
- package/extension/libherb/ast_nodes.c +180 -182
- package/extension/libherb/ast_nodes.h +69 -68
- package/extension/libherb/ast_pretty_print.c +233 -233
- package/extension/libherb/ast_pretty_print.h +3 -3
- package/extension/libherb/element_source.c +7 -6
- package/extension/libherb/element_source.h +3 -1
- package/extension/libherb/errors.c +273 -153
- package/extension/libherb/errors.h +43 -27
- package/extension/libherb/extract.c +92 -34
- package/extension/libherb/extract.h +4 -4
- package/extension/libherb/herb.c +37 -49
- package/extension/libherb/herb.h +6 -7
- package/extension/libherb/html_util.c +34 -96
- package/extension/libherb/html_util.h +4 -5
- package/extension/libherb/include/analyze.h +10 -2
- package/extension/libherb/include/analyze_helpers.h +3 -0
- package/extension/libherb/include/analyzed_ruby.h +4 -2
- package/extension/libherb/include/ast_node.h +4 -4
- package/extension/libherb/include/ast_nodes.h +69 -68
- package/extension/libherb/include/ast_pretty_print.h +3 -3
- package/extension/libherb/include/element_source.h +3 -1
- package/extension/libherb/include/errors.h +43 -27
- package/extension/libherb/include/extract.h +4 -4
- package/extension/libherb/include/herb.h +6 -7
- package/extension/libherb/include/html_util.h +4 -5
- package/extension/libherb/include/lexer.h +1 -3
- package/extension/libherb/include/lexer_peek_helpers.h +21 -19
- package/extension/libherb/include/lexer_struct.h +12 -10
- package/extension/libherb/include/location.h +10 -13
- package/extension/libherb/include/macros.h +4 -0
- package/extension/libherb/include/parser.h +12 -6
- package/extension/libherb/include/parser_helpers.h +26 -16
- package/extension/libherb/include/position.h +3 -14
- package/extension/libherb/include/pretty_print.h +38 -28
- package/extension/libherb/include/prism_helpers.h +1 -1
- package/extension/libherb/include/range.h +4 -13
- package/extension/libherb/include/token.h +5 -11
- package/extension/libherb/include/token_struct.h +2 -2
- package/extension/libherb/include/utf8.h +3 -2
- package/extension/libherb/include/util/hb_arena.h +31 -0
- package/extension/libherb/include/util/hb_arena_debug.h +8 -0
- package/extension/libherb/include/util/hb_array.h +33 -0
- package/extension/libherb/include/util/hb_buffer.h +34 -0
- package/extension/libherb/include/util/hb_string.h +29 -0
- package/extension/libherb/include/util/hb_system.h +9 -0
- package/extension/libherb/include/util.h +3 -14
- package/extension/libherb/include/version.h +1 -1
- package/extension/libherb/include/visitor.h +1 -1
- package/extension/libherb/io.c +7 -4
- package/extension/libherb/lexer.c +62 -88
- package/extension/libherb/lexer.h +1 -3
- package/extension/libherb/lexer_peek_helpers.c +42 -38
- package/extension/libherb/lexer_peek_helpers.h +21 -19
- package/extension/libherb/lexer_struct.h +12 -10
- package/extension/libherb/location.c +9 -37
- package/extension/libherb/location.h +10 -13
- package/extension/libherb/macros.h +4 -0
- package/extension/libherb/main.c +19 -23
- package/extension/libherb/parser.c +373 -313
- package/extension/libherb/parser.h +12 -6
- package/extension/libherb/parser_helpers.c +60 -54
- package/extension/libherb/parser_helpers.h +26 -16
- package/extension/libherb/parser_match_tags.c +316 -0
- package/extension/libherb/position.h +3 -14
- package/extension/libherb/pretty_print.c +88 -117
- package/extension/libherb/pretty_print.h +38 -28
- package/extension/libherb/prism_helpers.c +7 -7
- package/extension/libherb/prism_helpers.h +1 -1
- package/extension/libherb/range.c +2 -35
- package/extension/libherb/range.h +4 -13
- package/extension/libherb/token.c +36 -87
- package/extension/libherb/token.h +5 -11
- package/extension/libherb/token_struct.h +2 -2
- package/extension/libherb/utf8.c +4 -4
- package/extension/libherb/utf8.h +3 -2
- package/extension/libherb/util/hb_arena.c +179 -0
- package/extension/libherb/util/hb_arena.h +31 -0
- package/extension/libherb/util/hb_arena_debug.c +237 -0
- package/extension/libherb/util/hb_arena_debug.h +8 -0
- package/extension/libherb/{array.c → util/hb_array.c} +26 -27
- package/extension/libherb/util/hb_array.h +33 -0
- package/extension/libherb/util/hb_buffer.c +203 -0
- package/extension/libherb/util/hb_buffer.h +34 -0
- package/extension/libherb/util/hb_string.c +85 -0
- package/extension/libherb/util/hb_string.h +29 -0
- package/extension/libherb/util/hb_system.c +30 -0
- package/extension/libherb/util/hb_system.h +9 -0
- package/extension/libherb/util.c +29 -99
- package/extension/libherb/util.h +3 -14
- package/extension/libherb/version.h +1 -1
- package/extension/libherb/visitor.c +55 -55
- package/extension/libherb/visitor.h +1 -1
- package/extension/nodes.cpp +40 -40
- package/extension/nodes.h +2 -2
- package/extension/prism/include/prism/ast.h +31 -1
- package/extension/prism/include/prism/diagnostic.h +1 -0
- package/extension/prism/include/prism/version.h +3 -3
- package/extension/prism/src/diagnostic.c +3 -1
- package/extension/prism/src/prism.c +130 -71
- package/extension/prism/src/util/pm_string.c +6 -8
- package/package.json +3 -3
- package/extension/libherb/array.h +0 -33
- package/extension/libherb/buffer.c +0 -232
- package/extension/libherb/buffer.h +0 -39
- package/extension/libherb/include/array.h +0 -33
- package/extension/libherb/include/buffer.h +0 -39
- package/extension/libherb/include/json.h +0 -28
- package/extension/libherb/include/memory.h +0 -12
- package/extension/libherb/json.c +0 -205
- package/extension/libherb/json.h +0 -28
- package/extension/libherb/memory.c +0 -53
- package/extension/libherb/memory.h +0 -12
- package/extension/libherb/position.c +0 -33
|
@@ -1,37 +1,35 @@
|
|
|
1
1
|
#include "include/token.h"
|
|
2
|
-
#include "include/json.h"
|
|
3
2
|
#include "include/lexer.h"
|
|
4
3
|
#include "include/position.h"
|
|
4
|
+
#include "include/range.h"
|
|
5
5
|
#include "include/token_struct.h"
|
|
6
6
|
#include "include/util.h"
|
|
7
7
|
|
|
8
|
+
#include <stdbool.h>
|
|
8
9
|
#include <stdio.h>
|
|
9
10
|
#include <stdlib.h>
|
|
10
11
|
#include <string.h>
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
token_T* token_init(const char* value, const token_type_T type, lexer_T* lexer) {
|
|
17
|
-
token_T* token = calloc(1, token_sizeof());
|
|
13
|
+
token_T* token_init(hb_string_T value, const token_type_T type, lexer_T* lexer) {
|
|
14
|
+
token_T* token = calloc(1, sizeof(token_T));
|
|
18
15
|
|
|
19
16
|
if (type == TOKEN_NEWLINE) {
|
|
20
17
|
lexer->current_line++;
|
|
21
18
|
lexer->current_column = 0;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
token->value = herb_strdup(value);
|
|
26
|
-
} else {
|
|
27
|
-
token->value = NULL;
|
|
28
|
-
}
|
|
21
|
+
token->value = hb_string_to_c_string_using_malloc(value);
|
|
29
22
|
|
|
30
23
|
token->type = type;
|
|
31
|
-
token->range =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
token->range = (range_T) { .from = lexer->previous_position, .to = lexer->current_position };
|
|
25
|
+
|
|
26
|
+
location_from(
|
|
27
|
+
&token->location,
|
|
28
|
+
lexer->previous_line,
|
|
29
|
+
lexer->previous_column,
|
|
30
|
+
lexer->current_line,
|
|
31
|
+
lexer->current_column
|
|
32
|
+
);
|
|
35
33
|
|
|
36
34
|
lexer->previous_line = lexer->current_line;
|
|
37
35
|
lexer->previous_column = lexer->current_column;
|
|
@@ -82,93 +80,42 @@ const char* token_type_to_string(const token_type_T type) {
|
|
|
82
80
|
return "Unknown token_type_T";
|
|
83
81
|
}
|
|
84
82
|
|
|
85
|
-
|
|
83
|
+
hb_string_T token_to_string(const token_T* token) {
|
|
86
84
|
const char* type_string = token_type_to_string(token->type);
|
|
87
|
-
const char* template = "#<Herb::Token type=\"%s\" value=\"
|
|
85
|
+
const char* template = "#<Herb::Token type=\"%s\" value=\"%.*s\" range=[%u, %u] start=(%u:%u) end=(%u:%u)>";
|
|
88
86
|
|
|
89
87
|
char* string = calloc(strlen(type_string) + strlen(template) + strlen(token->value) + 16, sizeof(char));
|
|
90
|
-
|
|
88
|
+
hb_string_T escaped;
|
|
91
89
|
|
|
92
90
|
if (token->type == TOKEN_EOF) {
|
|
93
|
-
escaped = herb_strdup("<EOF>");
|
|
91
|
+
escaped = hb_string(herb_strdup("<EOF>"));
|
|
94
92
|
} else {
|
|
95
|
-
escaped = escape_newlines(token->value);
|
|
93
|
+
escaped = escape_newlines(hb_string(token->value));
|
|
96
94
|
}
|
|
97
95
|
|
|
98
96
|
sprintf(
|
|
99
97
|
string,
|
|
100
98
|
template,
|
|
101
99
|
type_string,
|
|
102
|
-
escaped,
|
|
103
|
-
|
|
104
|
-
token->range
|
|
105
|
-
token->
|
|
106
|
-
token->location
|
|
107
|
-
token->location
|
|
108
|
-
token->location
|
|
100
|
+
escaped.length,
|
|
101
|
+
escaped.data,
|
|
102
|
+
token->range.from,
|
|
103
|
+
token->range.to,
|
|
104
|
+
token->location.start.line,
|
|
105
|
+
token->location.start.column,
|
|
106
|
+
token->location.end.line,
|
|
107
|
+
token->location.end.column
|
|
109
108
|
);
|
|
110
109
|
|
|
111
|
-
free(escaped);
|
|
112
|
-
|
|
113
|
-
return string;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
char* token_to_json(const token_T* token) {
|
|
117
|
-
buffer_T json = buffer_new();
|
|
118
|
-
|
|
119
|
-
json_start_root_object(&json);
|
|
120
|
-
json_add_string(&json, "type", token_type_to_string(token->type));
|
|
121
|
-
json_add_string(&json, "value", token->value);
|
|
122
|
-
|
|
123
|
-
buffer_T range = buffer_new();
|
|
124
|
-
json_start_array(&json, "range");
|
|
125
|
-
json_add_size_t(&range, NULL, token->range->from);
|
|
126
|
-
json_add_size_t(&range, NULL, token->range->to);
|
|
127
|
-
buffer_concat(&json, &range);
|
|
128
|
-
buffer_free(&range);
|
|
129
|
-
json_end_array(&json);
|
|
130
|
-
|
|
131
|
-
buffer_T start = buffer_new();
|
|
132
|
-
json_start_object(&json, "start");
|
|
133
|
-
json_add_size_t(&start, "line", token->location->start->line);
|
|
134
|
-
json_add_size_t(&start, "column", token->location->start->column);
|
|
135
|
-
buffer_concat(&json, &start);
|
|
136
|
-
buffer_free(&start);
|
|
137
|
-
json_end_object(&json);
|
|
138
|
-
|
|
139
|
-
buffer_T end = buffer_new();
|
|
140
|
-
json_start_object(&json, "end");
|
|
141
|
-
json_add_size_t(&end, "line", token->location->end->line);
|
|
142
|
-
json_add_size_t(&end, "column", token->location->end->column);
|
|
143
|
-
buffer_concat(&json, &end);
|
|
144
|
-
buffer_free(&end);
|
|
145
|
-
json_end_object(&json);
|
|
146
|
-
|
|
147
|
-
json_end_object(&json);
|
|
148
|
-
|
|
149
|
-
return buffer_value(&json);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
char* token_value(const token_T* token) {
|
|
153
|
-
return token->value;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
int token_type(const token_T* token) {
|
|
157
|
-
return token->type;
|
|
158
|
-
}
|
|
110
|
+
free(escaped.data);
|
|
159
111
|
|
|
160
|
-
|
|
161
|
-
return token->location->start;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
position_T* token_end_position(token_T* token) {
|
|
165
|
-
return token->location->end;
|
|
112
|
+
return hb_string(string);
|
|
166
113
|
}
|
|
167
114
|
|
|
168
115
|
token_T* token_copy(token_T* token) {
|
|
169
116
|
if (!token) { return NULL; }
|
|
170
117
|
|
|
171
|
-
token_T* new_token = calloc(1,
|
|
118
|
+
token_T* new_token = calloc(1, sizeof(token_T));
|
|
172
119
|
|
|
173
120
|
if (!new_token) { return NULL; }
|
|
174
121
|
|
|
@@ -184,18 +131,20 @@ token_T* token_copy(token_T* token) {
|
|
|
184
131
|
}
|
|
185
132
|
|
|
186
133
|
new_token->type = token->type;
|
|
187
|
-
new_token->range =
|
|
188
|
-
new_token->location =
|
|
134
|
+
new_token->range = token->range;
|
|
135
|
+
new_token->location = token->location;
|
|
189
136
|
|
|
190
137
|
return new_token;
|
|
191
138
|
}
|
|
192
139
|
|
|
140
|
+
bool token_value_empty(const token_T* token) {
|
|
141
|
+
return token == NULL || token->value == NULL || token->value[0] == '\0';
|
|
142
|
+
}
|
|
143
|
+
|
|
193
144
|
void token_free(token_T* token) {
|
|
194
145
|
if (!token) { return; }
|
|
195
146
|
|
|
196
147
|
if (token->value != NULL) { free(token->value); }
|
|
197
|
-
if (token->range != NULL) { range_free(token->range); }
|
|
198
|
-
if (token->location != NULL) { location_free(token->location); }
|
|
199
148
|
|
|
200
149
|
free(token);
|
|
201
150
|
}
|
|
@@ -4,22 +4,16 @@
|
|
|
4
4
|
#include "lexer_struct.h"
|
|
5
5
|
#include "position.h"
|
|
6
6
|
#include "token_struct.h"
|
|
7
|
+
#include "util/hb_string.h"
|
|
7
8
|
|
|
8
|
-
token_T* token_init(
|
|
9
|
-
|
|
10
|
-
char* token_to_json(const token_T* token);
|
|
9
|
+
token_T* token_init(hb_string_T value, token_type_T type, lexer_T* lexer);
|
|
10
|
+
hb_string_T token_to_string(const token_T* token);
|
|
11
11
|
const char* token_type_to_string(token_type_T type);
|
|
12
12
|
|
|
13
|
-
char* token_value(const token_T* token);
|
|
14
|
-
int token_type(const token_T* token);
|
|
15
|
-
|
|
16
|
-
position_T* token_start_position(token_T* token);
|
|
17
|
-
position_T* token_end_position(token_T* token);
|
|
18
|
-
|
|
19
|
-
size_t token_sizeof(void);
|
|
20
|
-
|
|
21
13
|
token_T* token_copy(token_T* token);
|
|
22
14
|
|
|
23
15
|
void token_free(token_T* token);
|
|
24
16
|
|
|
17
|
+
bool token_value_empty(const token_T* token);
|
|
18
|
+
|
|
25
19
|
#endif
|
package/extension/libherb/utf8.c
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// 110xxxxx = 2 bytes
|
|
6
6
|
// 1110xxxx = 3 bytes
|
|
7
7
|
// 11110xxx = 4 bytes
|
|
8
|
-
|
|
8
|
+
uint32_t utf8_char_byte_length(unsigned char first_byte) {
|
|
9
9
|
if ((first_byte & 0x80) == 0) {
|
|
10
10
|
return 1;
|
|
11
11
|
} else if ((first_byte & 0xE0) == 0xC0) {
|
|
@@ -24,18 +24,18 @@ bool utf8_is_valid_continuation_byte(unsigned char byte) {
|
|
|
24
24
|
return (byte & 0xC0) == 0x80;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
uint32_t utf8_sequence_length(const char* str, size_t position, size_t max_length) {
|
|
28
28
|
if (position >= max_length) { return 0; }
|
|
29
29
|
|
|
30
30
|
unsigned char first_byte = (unsigned char) str[position];
|
|
31
|
-
|
|
31
|
+
uint32_t expected_length = utf8_char_byte_length(first_byte);
|
|
32
32
|
|
|
33
33
|
if (position + expected_length > max_length) {
|
|
34
34
|
return 1; // Not enough bytes, treat as single byte
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
if (expected_length > 1) {
|
|
38
|
-
for (
|
|
38
|
+
for (uint32_t i = 1; i < expected_length; i++) {
|
|
39
39
|
if (!utf8_is_valid_continuation_byte((unsigned char) str[position + i])) {
|
|
40
40
|
return 1; // Invalid continuation byte, treat first byte as single byte
|
|
41
41
|
}
|
package/extension/libherb/utf8.h
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
#define HERB_UTF8_H
|
|
3
3
|
|
|
4
4
|
#include <stdbool.h>
|
|
5
|
+
#include <stdint.h>
|
|
5
6
|
#include <stdlib.h>
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
uint32_t utf8_char_byte_length(unsigned char first_byte);
|
|
9
|
+
uint32_t utf8_sequence_length(const char* str, size_t position, size_t max_length);
|
|
9
10
|
bool utf8_is_valid_continuation_byte(unsigned char byte);
|
|
10
11
|
|
|
11
12
|
#endif
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#include "../include/util/hb_arena.h"
|
|
2
|
+
#include "../include/macros.h"
|
|
3
|
+
#include "../include/util/hb_system.h"
|
|
4
|
+
|
|
5
|
+
#include <assert.h>
|
|
6
|
+
#include <stdbool.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#define hb_arena_for_each_page(allocator, page) \
|
|
11
|
+
for (hb_arena_page_T* page = (allocator)->head; page != NULL; page = page->next)
|
|
12
|
+
|
|
13
|
+
static inline size_t hb_arena_align_size(size_t size, size_t alignment) {
|
|
14
|
+
assert(size <= SIZE_MAX - (alignment - 1));
|
|
15
|
+
|
|
16
|
+
return ((size + (alignment - 1)) / alignment) * alignment;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static inline bool hb_arena_page_has_capacity(hb_arena_page_T* page, size_t required_size) {
|
|
20
|
+
assert(page->position <= page->capacity);
|
|
21
|
+
|
|
22
|
+
return page->position + required_size <= page->capacity;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static inline void* hb_arena_page_alloc_from(hb_arena_page_T* page, size_t size) {
|
|
26
|
+
assert(size > 0);
|
|
27
|
+
assert(page->position + size <= page->capacity);
|
|
28
|
+
|
|
29
|
+
void* result = &page->memory[page->position];
|
|
30
|
+
page->position += size;
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static inline void hb_arena_page_reset(hb_arena_page_T* page) {
|
|
36
|
+
page->position = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
static inline void hb_arena_reset_pages_after(hb_arena_page_T* start_page) {
|
|
40
|
+
for (hb_arena_page_T* page = start_page; page != NULL; page = page->next) {
|
|
41
|
+
hb_arena_page_reset(page);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static bool hb_arena_append_page(hb_arena_T* allocator, size_t minimum_size) {
|
|
46
|
+
assert(minimum_size > 0);
|
|
47
|
+
|
|
48
|
+
size_t page_size = MAX(allocator->default_page_size, minimum_size);
|
|
49
|
+
|
|
50
|
+
assert(page_size <= SIZE_MAX - sizeof(hb_arena_page_T));
|
|
51
|
+
size_t total_size = page_size + sizeof(hb_arena_page_T);
|
|
52
|
+
|
|
53
|
+
hb_arena_page_T* page = hb_system_allocate_memory(total_size);
|
|
54
|
+
if (page == NULL) { return false; }
|
|
55
|
+
|
|
56
|
+
*page = (hb_arena_page_T) { .next = NULL, .capacity = page_size, .position = 0 };
|
|
57
|
+
|
|
58
|
+
if (allocator->head == NULL) {
|
|
59
|
+
allocator->head = page;
|
|
60
|
+
allocator->tail = page;
|
|
61
|
+
} else {
|
|
62
|
+
hb_arena_page_T* last = allocator->head;
|
|
63
|
+
|
|
64
|
+
while (last->next != NULL) {
|
|
65
|
+
last = last->next;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
last->next = page;
|
|
69
|
+
allocator->tail = page;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
bool hb_arena_init(hb_arena_T* allocator, size_t initial_size) {
|
|
76
|
+
assert(initial_size > 0);
|
|
77
|
+
|
|
78
|
+
allocator->head = NULL;
|
|
79
|
+
allocator->tail = NULL;
|
|
80
|
+
allocator->default_page_size = initial_size;
|
|
81
|
+
allocator->allocation_count = 0;
|
|
82
|
+
|
|
83
|
+
return hb_arena_append_page(allocator, initial_size);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void* hb_arena_alloc(hb_arena_T* allocator, size_t size) {
|
|
87
|
+
assert(allocator->tail != NULL);
|
|
88
|
+
assert(size > 0);
|
|
89
|
+
|
|
90
|
+
size_t required_size = hb_arena_align_size(size, 8);
|
|
91
|
+
|
|
92
|
+
allocator->allocation_count++;
|
|
93
|
+
|
|
94
|
+
if (hb_arena_page_has_capacity(allocator->tail, required_size)) {
|
|
95
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (hb_arena_page_T* page = allocator->tail->next; page != NULL; page = page->next) {
|
|
99
|
+
if (hb_arena_page_has_capacity(page, required_size)) {
|
|
100
|
+
allocator->tail = page;
|
|
101
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
bool allocated = hb_arena_append_page(allocator, required_size);
|
|
106
|
+
|
|
107
|
+
if (!allocated) { return NULL; }
|
|
108
|
+
|
|
109
|
+
return hb_arena_page_alloc_from(allocator->tail, required_size);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
size_t hb_arena_position(hb_arena_T* allocator) {
|
|
113
|
+
size_t total = 0;
|
|
114
|
+
|
|
115
|
+
hb_arena_for_each_page(allocator, page) {
|
|
116
|
+
total += page->position;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return total;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
size_t hb_arena_capacity(hb_arena_T* allocator) {
|
|
123
|
+
size_t total = 0;
|
|
124
|
+
|
|
125
|
+
hb_arena_for_each_page(allocator, page) {
|
|
126
|
+
total += page->capacity;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return total;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
void hb_arena_reset(hb_arena_T* allocator) {
|
|
133
|
+
hb_arena_for_each_page(allocator, page) {
|
|
134
|
+
hb_arena_page_reset(page);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
allocator->tail = allocator->head;
|
|
138
|
+
allocator->allocation_count = 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
void hb_arena_reset_to(hb_arena_T* allocator, size_t target_position) {
|
|
142
|
+
if (target_position == 0) {
|
|
143
|
+
hb_arena_reset(allocator);
|
|
144
|
+
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
size_t accumulated = 0;
|
|
149
|
+
|
|
150
|
+
hb_arena_for_each_page(allocator, page) {
|
|
151
|
+
if (accumulated + page->capacity >= target_position) {
|
|
152
|
+
page->position = target_position - accumulated;
|
|
153
|
+
allocator->tail = page;
|
|
154
|
+
|
|
155
|
+
hb_arena_reset_pages_after(page->next);
|
|
156
|
+
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
accumulated += page->capacity;
|
|
161
|
+
page->position = page->capacity;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
void hb_arena_free(hb_arena_T* allocator) {
|
|
166
|
+
if (allocator->head == NULL) { return; }
|
|
167
|
+
|
|
168
|
+
for (hb_arena_page_T* current = allocator->head; current != NULL;) {
|
|
169
|
+
hb_arena_page_T* next = current->next;
|
|
170
|
+
size_t total_size = sizeof(hb_arena_page_T) + current->capacity;
|
|
171
|
+
hb_system_free_memory(current, total_size);
|
|
172
|
+
|
|
173
|
+
current = next;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
allocator->head = NULL;
|
|
177
|
+
allocator->tail = NULL;
|
|
178
|
+
allocator->default_page_size = 0;
|
|
179
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#ifndef HERB_ARENA_H
|
|
2
|
+
#define HERB_ARENA_H
|
|
3
|
+
|
|
4
|
+
#include <stdbool.h>
|
|
5
|
+
#include <stddef.h>
|
|
6
|
+
|
|
7
|
+
typedef struct HB_ARENA_PAGE_STRUCT hb_arena_page_T;
|
|
8
|
+
|
|
9
|
+
struct HB_ARENA_PAGE_STRUCT {
|
|
10
|
+
hb_arena_page_T* next;
|
|
11
|
+
size_t capacity;
|
|
12
|
+
size_t position;
|
|
13
|
+
char memory[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
typedef struct HB_ARENA_STRUCT {
|
|
17
|
+
hb_arena_page_T* head;
|
|
18
|
+
hb_arena_page_T* tail;
|
|
19
|
+
size_t default_page_size;
|
|
20
|
+
size_t allocation_count;
|
|
21
|
+
} hb_arena_T;
|
|
22
|
+
|
|
23
|
+
bool hb_arena_init(hb_arena_T* allocator, size_t initial_size);
|
|
24
|
+
void* hb_arena_alloc(hb_arena_T* allocator, size_t size);
|
|
25
|
+
size_t hb_arena_position(hb_arena_T* allocator);
|
|
26
|
+
size_t hb_arena_capacity(hb_arena_T* allocator);
|
|
27
|
+
void hb_arena_reset(hb_arena_T* allocator);
|
|
28
|
+
void hb_arena_reset_to(hb_arena_T* allocator, size_t new_position);
|
|
29
|
+
void hb_arena_free(hb_arena_T* allocator);
|
|
30
|
+
|
|
31
|
+
#endif
|