yarp 0.10.0 → 0.12.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.
data/src/unescape.c CHANGED
@@ -94,7 +94,7 @@ static inline size_t
94
94
  unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end, yp_list_t *error_list) {
95
95
  *value = 0;
96
96
  if (backslash + 2 >= end || !yp_char_is_hexadecimal_digit(backslash[2])) {
97
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid hex escape.");
97
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_HEXADECIMAL);
98
98
  return 2;
99
99
  }
100
100
  *value = unescape_hexadecimal_digit(backslash[2]);
@@ -157,7 +157,7 @@ unescape_unicode_write(uint8_t *dest, uint32_t value, const uint8_t *start, cons
157
157
  // If we get here, then the value is too big. This is an error, but we don't
158
158
  // want to just crash, so instead we'll add an error to the error list and put
159
159
  // in a replacement character instead.
160
- if (error_list) yp_diagnostic_list_append(error_list, start, end, "Invalid Unicode escape sequence.");
160
+ if (error_list) yp_diagnostic_list_append(error_list, start, end, YP_ERR_ESCAPE_INVALID_UNICODE);
161
161
  dest[0] = 0xEF;
162
162
  dest[1] = 0xBF;
163
163
  dest[2] = 0xBD;
@@ -235,7 +235,7 @@ unescape(
235
235
  // \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F])
236
236
  case 'u': {
237
237
  if ((flags & YP_UNESCAPE_FLAG_CONTROL) | (flags & YP_UNESCAPE_FLAG_META)) {
238
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Unicode escape sequence cannot be used with control or meta flags.");
238
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS);
239
239
  return backslash + 2;
240
240
  }
241
241
 
@@ -252,11 +252,11 @@ unescape(
252
252
 
253
253
  // \u{nnnn} character literal allows only 1-6 hexadecimal digits
254
254
  if (hexadecimal_length > 6) {
255
- if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "invalid Unicode escape.");
255
+ if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE_LONG);
256
256
  }
257
257
  // there are not hexadecimal characters
258
258
  else if (hexadecimal_length == 0) {
259
- if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "unterminated Unicode escape");
259
+ if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE);
260
260
  return unicode_cursor;
261
261
  }
262
262
 
@@ -277,13 +277,13 @@ unescape(
277
277
 
278
278
  // ?\u{nnnn} character literal should contain only one codepoint and cannot be like ?\u{nnnn mmmm}
279
279
  if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1) {
280
- if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, "Multiple codepoints at single character literal");
280
+ if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL);
281
281
  }
282
282
 
283
283
  if (unicode_cursor < end && *unicode_cursor == '}') {
284
284
  unicode_cursor++;
285
285
  } else {
286
- if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, "invalid Unicode escape.");
286
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, YP_ERR_ESCAPE_INVALID_UNICODE_TERM);
287
287
  }
288
288
 
289
289
  return unicode_cursor;
@@ -298,7 +298,7 @@ unescape(
298
298
  return backslash + 6;
299
299
  }
300
300
 
301
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid Unicode escape sequence");
301
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE);
302
302
  return backslash + 2;
303
303
  }
304
304
  // \c\M-x meta control character, where x is an ASCII printable character
@@ -306,12 +306,12 @@ unescape(
306
306
  // \cx control character, where x is an ASCII printable character
307
307
  case 'c':
308
308
  if (backslash + 2 >= end) {
309
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
309
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
310
310
  return end;
311
311
  }
312
312
 
313
313
  if (flags & YP_UNESCAPE_FLAG_CONTROL) {
314
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled.");
314
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
315
315
  return backslash + 2;
316
316
  }
317
317
 
@@ -325,7 +325,7 @@ unescape(
325
325
  return backslash + 3;
326
326
  default: {
327
327
  if (!char_is_ascii_printable(backslash[2])) {
328
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
328
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
329
329
  return backslash + 2;
330
330
  }
331
331
 
@@ -339,17 +339,17 @@ unescape(
339
339
  // \C-? delete, ASCII 7Fh (DEL)
340
340
  case 'C':
341
341
  if (backslash + 3 >= end) {
342
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
342
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
343
343
  return end;
344
344
  }
345
345
 
346
346
  if (flags & YP_UNESCAPE_FLAG_CONTROL) {
347
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled.");
347
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT);
348
348
  return backslash + 2;
349
349
  }
350
350
 
351
351
  if (backslash[2] != '-') {
352
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
352
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL);
353
353
  return backslash + 2;
354
354
  }
355
355
 
@@ -363,7 +363,7 @@ unescape(
363
363
  return backslash + 4;
364
364
  default:
365
365
  if (!char_is_ascii_printable(backslash[3])) {
366
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid control escape sequence");
366
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_CONTROL);
367
367
  return backslash + 2;
368
368
  }
369
369
 
@@ -377,17 +377,17 @@ unescape(
377
377
  // \M-x meta character, where x is an ASCII printable character
378
378
  case 'M': {
379
379
  if (backslash + 3 >= end) {
380
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence");
380
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_META);
381
381
  return end;
382
382
  }
383
383
 
384
384
  if (flags & YP_UNESCAPE_FLAG_META) {
385
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Meta escape sequence cannot be doubled.");
385
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META_REPEAT);
386
386
  return backslash + 2;
387
387
  }
388
388
 
389
389
  if (backslash[2] != '-') {
390
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence");
390
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META);
391
391
  return backslash + 2;
392
392
  }
393
393
 
@@ -402,7 +402,7 @@ unescape(
402
402
  return backslash + 4;
403
403
  }
404
404
 
405
- if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence");
405
+ if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META);
406
406
  return backslash + 3;
407
407
  }
408
408
  // \n
@@ -474,7 +474,7 @@ yp_unescape_manipulate_string_or_char_literal(yp_parser_t *parser, yp_string_t *
474
474
  // within the string.
475
475
  uint8_t *allocated = malloc(string->length);
476
476
  if (allocated == NULL) {
477
- yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, "Failed to allocate memory for unescaping.");
477
+ yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, YP_ERR_MALLOC_FAILED);
478
478
  return;
479
479
  }
480
480
 
data/src/util/yp_char.c CHANGED
@@ -75,7 +75,7 @@ yp_strspn_whitespace(const uint8_t *string, ptrdiff_t length) {
75
75
  // whitespace while also tracking the location of each newline. Disallows
76
76
  // searching past the given maximum number of characters.
77
77
  size_t
78
- yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list, bool stop_at_newline) {
78
+ yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list) {
79
79
  if (length <= 0) return 0;
80
80
 
81
81
  size_t size = 0;
@@ -83,12 +83,7 @@ yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newlin
83
83
 
84
84
  while (size < maximum && (yp_byte_table[string[size]] & YP_CHAR_BIT_WHITESPACE)) {
85
85
  if (string[size] == '\n') {
86
- if (stop_at_newline) {
87
- return size + 1;
88
- }
89
- else {
90
- yp_newline_list_append(newline_list, string + size);
91
- }
86
+ yp_newline_list_append(newline_list, string + size);
92
87
  }
93
88
 
94
89
  size++;
@@ -128,6 +123,9 @@ yp_char_is_inline_whitespace(const uint8_t b) {
128
123
  return yp_char_is_char_kind(b, YP_CHAR_BIT_INLINE_WHITESPACE);
129
124
  }
130
125
 
126
+ // Scan through the string and return the number of characters at the start of
127
+ // the string that match the given kind. Disallows searching past the given
128
+ // maximum number of characters.
131
129
  static inline size_t
132
130
  yp_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
133
131
  if (length <= 0) return 0;
@@ -139,20 +137,57 @@ yp_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) {
139
137
  return size;
140
138
  }
141
139
 
140
+ // Scan through the string and return the number of characters at the start of
141
+ // the string that match the given kind. Disallows searching past the given
142
+ // maximum number of characters.
143
+ //
144
+ // Additionally, report the location of the last invalid underscore character
145
+ // found in the string through the out invalid parameter.
146
+ static inline size_t
147
+ yp_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) {
148
+ if (length <= 0) return 0;
149
+
150
+ size_t size = 0;
151
+ size_t maximum = (size_t) length;
152
+
153
+ bool underscore = false;
154
+ while (size < maximum && (yp_number_table[string[size]] & kind)) {
155
+ if (string[size] == '_') {
156
+ if (underscore) *invalid = string + size;
157
+ underscore = true;
158
+ } else {
159
+ underscore = false;
160
+ }
161
+
162
+ size++;
163
+ }
164
+
165
+ if (string[size - 1] == '_') *invalid = string + size - 1;
166
+ return size;
167
+ }
168
+
142
169
  // Returns the number of characters at the start of the string that are binary
143
170
  // digits or underscores. Disallows searching past the given maximum number of
144
171
  // characters.
172
+ //
173
+ // If multiple underscores are found in a row or if an underscore is
174
+ // found at the end of the number, then the invalid pointer is set to the index
175
+ // of the first invalid underscore.
145
176
  size_t
146
- yp_strspn_binary_number(const uint8_t *string, ptrdiff_t length) {
147
- return yp_strspn_number_kind(string, length, YP_NUMBER_BIT_BINARY_NUMBER);
177
+ yp_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
178
+ return yp_strspn_number_kind_underscores(string, length, invalid, YP_NUMBER_BIT_BINARY_NUMBER);
148
179
  }
149
180
 
150
181
  // Returns the number of characters at the start of the string that are octal
151
- // digits or underscores. Disallows searching past the given maximum number of
182
+ // digits or underscores. Disallows searching past the given maximum number of
152
183
  // characters.
184
+ //
185
+ // If multiple underscores are found in a row or if an underscore is
186
+ // found at the end of the number, then the invalid pointer is set to the index
187
+ // of the first invalid underscore.
153
188
  size_t
154
- yp_strspn_octal_number(const uint8_t *string, ptrdiff_t length) {
155
- return yp_strspn_number_kind(string, length, YP_NUMBER_BIT_OCTAL_NUMBER);
189
+ yp_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
190
+ return yp_strspn_number_kind_underscores(string, length, invalid, YP_NUMBER_BIT_OCTAL_NUMBER);
156
191
  }
157
192
 
158
193
  // Returns the number of characters at the start of the string that are decimal
@@ -165,9 +200,13 @@ yp_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) {
165
200
  // Returns the number of characters at the start of the string that are decimal
166
201
  // digits or underscores. Disallows searching past the given maximum number of
167
202
  // characters.
203
+ //
204
+ // If multiple underscores are found in a row or if an underscore is
205
+ // found at the end of the number, then the invalid pointer is set to the index
206
+ // of the first invalid underscore.
168
207
  size_t
169
- yp_strspn_decimal_number(const uint8_t *string, ptrdiff_t length) {
170
- return yp_strspn_number_kind(string, length, YP_NUMBER_BIT_DECIMAL_NUMBER);
208
+ yp_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
209
+ return yp_strspn_number_kind_underscores(string, length, invalid, YP_NUMBER_BIT_DECIMAL_NUMBER);
171
210
  }
172
211
 
173
212
  // Returns the number of characters at the start of the string that are
@@ -181,9 +220,13 @@ yp_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) {
181
220
  // Returns the number of characters at the start of the string that are
182
221
  // hexadecimal digits or underscores. Disallows searching past the given maximum
183
222
  // number of characters.
223
+ //
224
+ // If multiple underscores are found in a row or if an underscore is
225
+ // found at the end of the number, then the invalid pointer is set to the index
226
+ // of the first invalid underscore.
184
227
  size_t
185
- yp_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length) {
186
- return yp_strspn_number_kind(string, length, YP_NUMBER_BIT_HEXADECIMAL_NUMBER);
228
+ yp_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) {
229
+ return yp_strspn_number_kind_underscores(string, length, invalid, YP_NUMBER_BIT_HEXADECIMAL_NUMBER);
187
230
  }
188
231
 
189
232
  static inline bool
@@ -59,10 +59,42 @@ yp_constant_pool_hash(const uint8_t *start, size_t length) {
59
59
  return value;
60
60
  }
61
61
 
62
+ // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
63
+ static size_t
64
+ next_power_of_two(size_t v) {
65
+ // Avoid underflow in subtraction on next line.
66
+ if (v == 0) {
67
+ // 1 is the nearest power of 2 to 0 (2^0)
68
+ return 1;
69
+ }
70
+ v--;
71
+ v |= v >> 1;
72
+ v |= v >> 2;
73
+ v |= v >> 4;
74
+ v |= v >> 8;
75
+ v |= v >> 16;
76
+ #if defined(__LP64__) || defined(_WIN64)
77
+ v |= v >> 32;
78
+ #endif
79
+ v++;
80
+ return v;
81
+ }
82
+
83
+ #ifndef NDEBUG
84
+ static bool
85
+ is_power_of_two(size_t size) {
86
+ return (size & (size - 1)) == 0;
87
+ }
88
+ #endif
89
+
62
90
  // Resize a constant pool to a given capacity.
63
91
  static inline bool
64
92
  yp_constant_pool_resize(yp_constant_pool_t *pool) {
93
+ assert(is_power_of_two(pool->capacity));
65
94
  size_t next_capacity = pool->capacity * 2;
95
+ if (next_capacity < pool->capacity) return false;
96
+
97
+ const size_t mask = next_capacity - 1;
66
98
  yp_constant_t *next_constants = calloc(next_capacity, sizeof(yp_constant_t));
67
99
  if (next_constants == NULL) return false;
68
100
 
@@ -74,13 +106,13 @@ yp_constant_pool_resize(yp_constant_pool_t *pool) {
74
106
  // If an id is set on this constant, then we know we have content here.
75
107
  // In this case we need to insert it into the next constant pool.
76
108
  if (constant->id != 0) {
77
- size_t next_index = constant->hash % next_capacity;
109
+ size_t next_index = constant->hash & mask;
78
110
 
79
111
  // This implements linear scanning to find the next available slot
80
112
  // in case this index is already taken. We don't need to bother
81
113
  // comparing the values since we know that the hash is unique.
82
114
  while (next_constants[next_index].id != 0) {
83
- next_index = (next_index + 1) % next_capacity;
115
+ next_index = (next_index + 1) & mask;
84
116
  }
85
117
 
86
118
  // Here we copy over the entire constant, which includes the id so
@@ -98,6 +130,10 @@ yp_constant_pool_resize(yp_constant_pool_t *pool) {
98
130
  // Initialize a new constant pool with a given capacity.
99
131
  bool
100
132
  yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity) {
133
+ const size_t size_t_max = (~((size_t) 0));
134
+ if (capacity >= ((size_t_max / 2) + 1)) return false;
135
+
136
+ capacity = next_power_of_two(capacity);
101
137
  pool->constants = calloc(capacity, sizeof(yp_constant_t));
102
138
  if (pool->constants == NULL) return false;
103
139
 
@@ -106,16 +142,17 @@ yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity) {
106
142
  return true;
107
143
  }
108
144
 
109
- // Insert a constant into a constant pool. Returns the id of the constant, or 0
110
- // if any potential calls to resize fail.
111
- yp_constant_id_t
112
- yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t length) {
145
+ // Insert a constant into a constant pool and return its index in the pool.
146
+ static inline yp_constant_id_t
147
+ yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t length, bool owned) {
113
148
  if (pool->size >= (pool->capacity / 4 * 3)) {
114
149
  if (!yp_constant_pool_resize(pool)) return 0;
115
150
  }
116
151
 
152
+ assert(is_power_of_two(pool->capacity));
153
+ const size_t mask = pool->capacity - 1;
117
154
  size_t hash = yp_constant_pool_hash(start, length);
118
- size_t index = hash % pool->capacity;
155
+ size_t index = hash & mask;
119
156
  yp_constant_t *constant;
120
157
 
121
158
  while (constant = &pool->constants[index], constant->id != 0) {
@@ -123,25 +160,72 @@ yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t l
123
160
  // same as the content we are trying to insert. If it is, then we can
124
161
  // return the id of the existing constant.
125
162
  if ((constant->length == length) && memcmp(constant->start, start, length) == 0) {
126
- return pool->constants[index].id;
163
+ // Since we have found a match, we need to check if this is
164
+ // attempting to insert a shared or an owned constant. We want to
165
+ // prefer shared constants since they don't require allocations.
166
+ if (owned) {
167
+ // If we're attempting to insert an owned constant and we have
168
+ // an existing constant, then either way we don't want the given
169
+ // memory. Either it's duplicated with the existing constant or
170
+ // it's not necessary because we have a shared version.
171
+ free((void *) start);
172
+ } else if (constant->owned) {
173
+ // If we're attempting to insert a shared constant and the
174
+ // existing constant is owned, then we can free the owned
175
+ // constant and replace it with the shared constant.
176
+ free((void *) constant->start);
177
+ constant->start = start;
178
+ constant->owned = false;
179
+ }
180
+
181
+ return constant->id;
127
182
  }
128
183
 
129
- index = (index + 1) % pool->capacity;
184
+ index = (index + 1) & mask;
130
185
  }
131
186
 
132
- yp_constant_id_t id = (yp_constant_id_t)++pool->size;
133
- pool->constants[index] = (yp_constant_t) {
134
- .id = id,
187
+ pool->size++;
188
+ assert(pool->size < ((size_t) (1 << 31)));
189
+
190
+ *constant = (yp_constant_t) {
191
+ .id = (unsigned int) (pool->size & 0x7FFFFFFF),
192
+ .owned = owned,
135
193
  .start = start,
136
194
  .length = length,
137
195
  .hash = hash
138
196
  };
139
197
 
140
- return id;
198
+ return constant->id;
199
+ }
200
+
201
+ // Insert a constant into a constant pool. Returns the id of the constant, or 0
202
+ // if any potential calls to resize fail.
203
+ yp_constant_id_t
204
+ yp_constant_pool_insert_shared(yp_constant_pool_t *pool, const uint8_t *start, size_t length) {
205
+ return yp_constant_pool_insert(pool, start, length, false);
206
+ }
207
+
208
+ // Insert a constant into a constant pool from memory that is now owned by the
209
+ // constant pool. Returns the id of the constant, or 0 if any potential calls to
210
+ // resize fail.
211
+ yp_constant_id_t
212
+ yp_constant_pool_insert_owned(yp_constant_pool_t *pool, const uint8_t *start, size_t length) {
213
+ return yp_constant_pool_insert(pool, start, length, true);
141
214
  }
142
215
 
143
216
  // Free the memory associated with a constant pool.
144
217
  void
145
218
  yp_constant_pool_free(yp_constant_pool_t *pool) {
219
+ // For each constant in the current constant pool, free the contents if the
220
+ // contents are owned.
221
+ for (uint32_t index = 0; index < pool->capacity; index++) {
222
+ yp_constant_t *constant = &pool->constants[index];
223
+
224
+ // If an id is set on this constant, then we know we have content here.
225
+ if (constant->id != 0 && constant->owned) {
226
+ free((void *) constant->start);
227
+ }
228
+ }
229
+
146
230
  free(pool->constants);
147
231
  }
@@ -25,8 +25,12 @@ yp_newline_list_init(yp_newline_list_t *list, const uint8_t *start, size_t capac
25
25
  bool
26
26
  yp_newline_list_append(yp_newline_list_t *list, const uint8_t *cursor) {
27
27
  if (list->size == list->capacity) {
28
+ size_t *original_offsets = list->offsets;
29
+
28
30
  list->capacity = (list->capacity * 3) / 2;
29
- list->offsets = (size_t *) realloc(list->offsets, list->capacity * sizeof(size_t));
31
+ list->offsets = (size_t *) calloc(list->capacity, sizeof(size_t));
32
+ memcpy(list->offsets, original_offsets, list->size * sizeof(size_t));
33
+ free(original_offsets);
30
34
  if (list->offsets == NULL) return false;
31
35
  }
32
36
 
@@ -12,8 +12,11 @@ yp_string_list_init(yp_string_list_t *string_list) {
12
12
  void
13
13
  yp_string_list_append(yp_string_list_t *string_list, yp_string_t *string) {
14
14
  if (string_list->length + 1 > string_list->capacity) {
15
+ yp_string_t *original_string = string_list->strings;
15
16
  string_list->capacity *= 2;
16
- string_list->strings = (yp_string_t *) realloc(string_list->strings, string_list->capacity * sizeof(yp_string_t));
17
+ string_list->strings = (yp_string_t *) malloc(string_list->capacity * sizeof(yp_string_t));
18
+ memcpy(string_list->strings, original_string, (string_list->length) * sizeof(yp_string_t));
19
+ free(original_string);
17
20
  }
18
21
 
19
22
  string_list->strings[string_list->length++] = *string;