@@ -25,26 +25,41 @@ static VALUE Herb_lex(int argc, VALUE* argv, VALUE self) {
2525
2626 char * string = (char * ) check_string (source );
2727 bool print_arena_stats = false;
28+ VALUE external_arena = Qnil ;
2829
2930 if (!NIL_P (options )) {
3031 VALUE arena_stats = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena_stats" ));
3132 if (NIL_P (arena_stats )) { arena_stats = rb_hash_lookup (options , ID2SYM (rb_intern ("arena_stats" ))); }
3233 if (!NIL_P (arena_stats ) && RTEST (arena_stats )) { print_arena_stats = true; }
34+
35+ external_arena = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena" ));
36+ if (NIL_P (external_arena )) { external_arena = rb_hash_lookup (options , ID2SYM (rb_intern ("arena" ))); }
3337 }
3438
35- hb_arena_T * arena = malloc ( sizeof ( hb_arena_T )) ;
36- if (! arena ) { return Qnil ; }
39+ hb_arena_T * arena ;
40+ bool owns_arena ;
3741
38- if (!hb_arena_init (arena , KB (512 ))) {
39- free (arena );
40- return Qnil ;
42+ if (!NIL_P (external_arena )) {
43+ arena = get_arena_from_value (external_arena );
44+ owns_arena = false;
45+ } else {
46+ arena = malloc (sizeof (hb_arena_T ));
47+ if (!arena ) { return Qnil ; }
48+
49+ if (!hb_arena_init (arena , KB (512 ))) {
50+ free (arena );
51+ return Qnil ;
52+ }
53+ owns_arena = true;
4154 }
4255
4356 herb_lex_result_T * lex_result = herb_lex (string , arena );
4457
4558 if (!lex_result ) {
46- hb_arena_free (arena );
47- free (arena );
59+ if (owns_arena ) {
60+ hb_arena_free (arena );
61+ free (arena );
62+ }
4863 return Qnil ;
4964 }
5065
@@ -63,26 +78,41 @@ static VALUE Herb_lex_file(int argc, VALUE* argv, VALUE self) {
6378
6479 char * file_path = (char * ) check_string (path );
6580 bool print_arena_stats = false;
81+ VALUE external_arena = Qnil ;
6682
6783 if (!NIL_P (options )) {
6884 VALUE arena_stats = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena_stats" ));
6985 if (NIL_P (arena_stats )) { arena_stats = rb_hash_lookup (options , ID2SYM (rb_intern ("arena_stats" ))); }
7086 if (!NIL_P (arena_stats ) && RTEST (arena_stats )) { print_arena_stats = true; }
87+
88+ external_arena = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena" ));
89+ if (NIL_P (external_arena )) { external_arena = rb_hash_lookup (options , ID2SYM (rb_intern ("arena" ))); }
7190 }
7291
73- hb_arena_T * arena = malloc ( sizeof ( hb_arena_T )) ;
74- if (! arena ) { return Qnil ; }
92+ hb_arena_T * arena ;
93+ bool owns_arena ;
7594
76- if (!hb_arena_init (arena , KB (512 ))) {
77- free (arena );
78- return Qnil ;
95+ if (!NIL_P (external_arena )) {
96+ arena = get_arena_from_value (external_arena );
97+ owns_arena = false;
98+ } else {
99+ arena = malloc (sizeof (hb_arena_T ));
100+ if (!arena ) { return Qnil ; }
101+
102+ if (!hb_arena_init (arena , KB (512 ))) {
103+ free (arena );
104+ return Qnil ;
105+ }
106+ owns_arena = true;
79107 }
80108
81109 herb_lex_result_T * lex_result = herb_lex_file (file_path , arena );
82110
83111 if (!lex_result ) {
84- hb_arena_free (arena );
85- free (arena );
112+ if (owns_arena ) {
113+ hb_arena_free (arena );
114+ free (arena );
115+ }
86116 return Qnil ;
87117 }
88118
@@ -176,6 +206,7 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {
176206
177207 parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS ;
178208 bool print_arena_stats = false;
209+ VALUE external_arena = Qnil ;
179210
180211 if (!NIL_P (options )) {
181212 VALUE track_whitespace = rb_hash_lookup (options , rb_utf8_str_new_cstr ("track_whitespace" ));
@@ -193,24 +224,40 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {
193224 VALUE arena_stats = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena_stats" ));
194225 if (NIL_P (arena_stats )) { arena_stats = rb_hash_lookup (options , ID2SYM (rb_intern ("arena_stats" ))); }
195226 if (!NIL_P (arena_stats ) && RTEST (arena_stats )) { print_arena_stats = true; }
227+
228+ external_arena = rb_hash_lookup (options , rb_utf8_str_new_cstr ("arena" ));
229+ if (NIL_P (external_arena )) { external_arena = rb_hash_lookup (options , ID2SYM (rb_intern ("arena" ))); }
196230 }
197231
198- hb_arena_T * arena = malloc ( sizeof ( hb_arena_T )) ;
199- if (! arena ) { return Qnil ; }
232+ hb_arena_T * arena ;
233+ bool owns_arena ;
200234
201- if (!hb_arena_init (arena , KB (512 ))) {
202- free (arena );
203- return Qnil ;
235+ if (!NIL_P (external_arena )) {
236+ arena = get_arena_from_value (external_arena );
237+ owns_arena = false;
238+ } else {
239+ arena = malloc (sizeof (hb_arena_T ));
240+ if (!arena ) { return Qnil ; }
241+
242+ if (!hb_arena_init (arena , KB (512 ))) {
243+ free (arena );
244+ return Qnil ;
245+ }
246+ owns_arena = true;
204247 }
205248
206249 AST_DOCUMENT_NODE_T * root = herb_parse (string , & parser_options , arena );
207250
208251 if (!root ) {
209- hb_arena_free (arena );
210- free (arena );
252+ if (owns_arena ) {
253+ hb_arena_free (arena );
254+ free (arena );
255+ }
211256 return Qnil ;
212257 }
213258
259+ root -> owns_arena = owns_arena ;
260+
214261 VALUE result = create_parse_result (root , source_value );
215262
216263 if (print_arena_stats ) { hb_arena_print_stats (arena ); }
0 commit comments